ipv4addr.go 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. package sockaddr
  2. import (
  3. "encoding/binary"
  4. "fmt"
  5. "net"
  6. "regexp"
  7. "strconv"
  8. "strings"
  9. )
  10. type (
  11. // IPv4Address is a named type representing an IPv4 address.
  12. IPv4Address uint32
  13. // IPv4Network is a named type representing an IPv4 network.
  14. IPv4Network uint32
  15. // IPv4Mask is a named type representing an IPv4 network mask.
  16. IPv4Mask uint32
  17. )
  18. // IPv4HostMask is a constant represents a /32 IPv4 Address
  19. // (i.e. 255.255.255.255).
  20. const IPv4HostMask = IPv4Mask(0xffffffff)
  21. // ipv4AddrAttrMap is a map of the IPv4Addr type-specific attributes.
  22. var ipv4AddrAttrMap map[AttrName]func(IPv4Addr) string
  23. var ipv4AddrAttrs []AttrName
  24. var trailingHexNetmaskRE *regexp.Regexp
  25. // IPv4Addr implements a convenience wrapper around the union of Go's
  26. // built-in net.IP and net.IPNet types. In UNIX-speak, IPv4Addr implements
  27. // `sockaddr` when the the address family is set to AF_INET
  28. // (i.e. `sockaddr_in`).
  29. type IPv4Addr struct {
  30. IPAddr
  31. Address IPv4Address
  32. Mask IPv4Mask
  33. Port IPPort
  34. }
  35. func init() {
  36. ipv4AddrInit()
  37. trailingHexNetmaskRE = regexp.MustCompile(`/([0f]{8})$`)
  38. }
  39. // NewIPv4Addr creates an IPv4Addr from a string. String can be in the form
  40. // of either an IPv4:port (e.g. `1.2.3.4:80`, in which case the mask is
  41. // assumed to be a `/32`), an IPv4 address (e.g. `1.2.3.4`, also with a `/32`
  42. // mask), or an IPv4 CIDR (e.g. `1.2.3.4/24`, which has its IP port
  43. // initialized to zero). ipv4Str can not be a hostname.
  44. //
  45. // NOTE: Many net.*() routines will initialize and return an IPv6 address.
  46. // To create uint32 values from net.IP, always test to make sure the address
  47. // returned can be converted to a 4 byte array using To4().
  48. func NewIPv4Addr(ipv4Str string) (IPv4Addr, error) {
  49. // Strip off any bogus hex-encoded netmasks that will be mis-parsed by Go. In
  50. // particular, clients with the Barracuda VPN client will see something like:
  51. // `192.168.3.51/00ffffff` as their IP address.
  52. trailingHexNetmaskRe := trailingHexNetmaskRE.Copy()
  53. if match := trailingHexNetmaskRe.FindStringIndex(ipv4Str); match != nil {
  54. ipv4Str = ipv4Str[:match[0]]
  55. }
  56. // Parse as an IPv4 CIDR
  57. ipAddr, network, err := net.ParseCIDR(ipv4Str)
  58. if err == nil {
  59. ipv4 := ipAddr.To4()
  60. if ipv4 == nil {
  61. return IPv4Addr{}, fmt.Errorf("Unable to convert %s to an IPv4 address", ipv4Str)
  62. }
  63. // If we see an IPv6 netmask, convert it to an IPv4 mask.
  64. netmaskSepPos := strings.LastIndexByte(ipv4Str, '/')
  65. if netmaskSepPos != -1 && netmaskSepPos+1 < len(ipv4Str) {
  66. netMask, err := strconv.ParseUint(ipv4Str[netmaskSepPos+1:], 10, 8)
  67. if err != nil {
  68. return IPv4Addr{}, fmt.Errorf("Unable to convert %s to an IPv4 address: unable to parse CIDR netmask: %v", ipv4Str, err)
  69. } else if netMask > 128 {
  70. return IPv4Addr{}, fmt.Errorf("Unable to convert %s to an IPv4 address: invalid CIDR netmask", ipv4Str)
  71. }
  72. if netMask >= 96 {
  73. // Convert the IPv6 netmask to an IPv4 netmask
  74. network.Mask = net.CIDRMask(int(netMask-96), IPv4len*8)
  75. }
  76. }
  77. ipv4Addr := IPv4Addr{
  78. Address: IPv4Address(binary.BigEndian.Uint32(ipv4)),
  79. Mask: IPv4Mask(binary.BigEndian.Uint32(network.Mask)),
  80. }
  81. return ipv4Addr, nil
  82. }
  83. // Attempt to parse ipv4Str as a /32 host with a port number.
  84. tcpAddr, err := net.ResolveTCPAddr("tcp4", ipv4Str)
  85. if err == nil {
  86. ipv4 := tcpAddr.IP.To4()
  87. if ipv4 == nil {
  88. return IPv4Addr{}, fmt.Errorf("Unable to resolve %+q as an IPv4 address", ipv4Str)
  89. }
  90. ipv4Uint32 := binary.BigEndian.Uint32(ipv4)
  91. ipv4Addr := IPv4Addr{
  92. Address: IPv4Address(ipv4Uint32),
  93. Mask: IPv4HostMask,
  94. Port: IPPort(tcpAddr.Port),
  95. }
  96. return ipv4Addr, nil
  97. }
  98. // Parse as a naked IPv4 address
  99. ip := net.ParseIP(ipv4Str)
  100. if ip != nil {
  101. ipv4 := ip.To4()
  102. if ipv4 == nil {
  103. return IPv4Addr{}, fmt.Errorf("Unable to string convert %+q to an IPv4 address", ipv4Str)
  104. }
  105. ipv4Uint32 := binary.BigEndian.Uint32(ipv4)
  106. ipv4Addr := IPv4Addr{
  107. Address: IPv4Address(ipv4Uint32),
  108. Mask: IPv4HostMask,
  109. }
  110. return ipv4Addr, nil
  111. }
  112. return IPv4Addr{}, fmt.Errorf("Unable to parse %+q to an IPv4 address: %v", ipv4Str, err)
  113. }
  114. // AddressBinString returns a string with the IPv4Addr's Address represented
  115. // as a sequence of '0' and '1' characters. This method is useful for
  116. // debugging or by operators who want to inspect an address.
  117. func (ipv4 IPv4Addr) AddressBinString() string {
  118. return fmt.Sprintf("%032s", strconv.FormatUint(uint64(ipv4.Address), 2))
  119. }
  120. // AddressHexString returns a string with the IPv4Addr address represented as
  121. // a sequence of hex characters. This method is useful for debugging or by
  122. // operators who want to inspect an address.
  123. func (ipv4 IPv4Addr) AddressHexString() string {
  124. return fmt.Sprintf("%08s", strconv.FormatUint(uint64(ipv4.Address), 16))
  125. }
  126. // Broadcast is an IPv4Addr-only method that returns the broadcast address of
  127. // the network.
  128. //
  129. // NOTE: IPv6 only supports multicast, so this method only exists for
  130. // IPv4Addr.
  131. func (ipv4 IPv4Addr) Broadcast() IPAddr {
  132. // Nothing should listen on a broadcast address.
  133. return IPv4Addr{
  134. Address: IPv4Address(ipv4.BroadcastAddress()),
  135. Mask: IPv4HostMask,
  136. }
  137. }
  138. // BroadcastAddress returns a IPv4Network of the IPv4Addr's broadcast
  139. // address.
  140. func (ipv4 IPv4Addr) BroadcastAddress() IPv4Network {
  141. return IPv4Network(uint32(ipv4.Address)&uint32(ipv4.Mask) | ^uint32(ipv4.Mask))
  142. }
  143. // CmpAddress follows the Cmp() standard protocol and returns:
  144. //
  145. // - -1 If the receiver should sort first because its address is lower than arg
  146. // - 0 if the SockAddr arg is equal to the receiving IPv4Addr or the argument is
  147. // of a different type.
  148. // - 1 If the argument should sort first.
  149. func (ipv4 IPv4Addr) CmpAddress(sa SockAddr) int {
  150. ipv4b, ok := sa.(IPv4Addr)
  151. if !ok {
  152. return sortDeferDecision
  153. }
  154. switch {
  155. case ipv4.Address == ipv4b.Address:
  156. return sortDeferDecision
  157. case ipv4.Address < ipv4b.Address:
  158. return sortReceiverBeforeArg
  159. default:
  160. return sortArgBeforeReceiver
  161. }
  162. }
  163. // CmpPort follows the Cmp() standard protocol and returns:
  164. //
  165. // - -1 If the receiver should sort first because its port is lower than arg
  166. // - 0 if the SockAddr arg's port number is equal to the receiving IPv4Addr,
  167. // regardless of type.
  168. // - 1 If the argument should sort first.
  169. func (ipv4 IPv4Addr) CmpPort(sa SockAddr) int {
  170. var saPort IPPort
  171. switch v := sa.(type) {
  172. case IPv4Addr:
  173. saPort = v.Port
  174. case IPv6Addr:
  175. saPort = v.Port
  176. default:
  177. return sortDeferDecision
  178. }
  179. switch {
  180. case ipv4.Port == saPort:
  181. return sortDeferDecision
  182. case ipv4.Port < saPort:
  183. return sortReceiverBeforeArg
  184. default:
  185. return sortArgBeforeReceiver
  186. }
  187. }
  188. // CmpRFC follows the Cmp() standard protocol and returns:
  189. //
  190. // - -1 If the receiver should sort first because it belongs to the RFC and its
  191. // arg does not
  192. // - 0 if the receiver and arg both belong to the same RFC or neither do.
  193. // - 1 If the arg belongs to the RFC but receiver does not.
  194. func (ipv4 IPv4Addr) CmpRFC(rfcNum uint, sa SockAddr) int {
  195. recvInRFC := IsRFC(rfcNum, ipv4)
  196. ipv4b, ok := sa.(IPv4Addr)
  197. if !ok {
  198. // If the receiver is part of the desired RFC and the SockAddr
  199. // argument is not, return -1 so that the receiver sorts before
  200. // the non-IPv4 SockAddr. Conversely, if the receiver is not
  201. // part of the RFC, punt on sorting and leave it for the next
  202. // sorter.
  203. if recvInRFC {
  204. return sortReceiverBeforeArg
  205. } else {
  206. return sortDeferDecision
  207. }
  208. }
  209. argInRFC := IsRFC(rfcNum, ipv4b)
  210. switch {
  211. case (recvInRFC && argInRFC), (!recvInRFC && !argInRFC):
  212. // If a and b both belong to the RFC, or neither belong to
  213. // rfcNum, defer sorting to the next sorter.
  214. return sortDeferDecision
  215. case recvInRFC && !argInRFC:
  216. return sortReceiverBeforeArg
  217. default:
  218. return sortArgBeforeReceiver
  219. }
  220. }
  221. // Contains returns true if the SockAddr is contained within the receiver.
  222. func (ipv4 IPv4Addr) Contains(sa SockAddr) bool {
  223. ipv4b, ok := sa.(IPv4Addr)
  224. if !ok {
  225. return false
  226. }
  227. return ipv4.ContainsNetwork(ipv4b)
  228. }
  229. // ContainsAddress returns true if the IPv4Address is contained within the
  230. // receiver.
  231. func (ipv4 IPv4Addr) ContainsAddress(x IPv4Address) bool {
  232. return IPv4Address(ipv4.NetworkAddress()) <= x &&
  233. IPv4Address(ipv4.BroadcastAddress()) >= x
  234. }
  235. // ContainsNetwork returns true if the network from IPv4Addr is contained
  236. // within the receiver.
  237. func (ipv4 IPv4Addr) ContainsNetwork(x IPv4Addr) bool {
  238. return ipv4.NetworkAddress() <= x.NetworkAddress() &&
  239. ipv4.BroadcastAddress() >= x.BroadcastAddress()
  240. }
  241. // DialPacketArgs returns the arguments required to be passed to
  242. // net.DialUDP(). If the Mask of ipv4 is not a /32 or the Port is 0,
  243. // DialPacketArgs() will fail. See Host() to create an IPv4Addr with its
  244. // mask set to /32.
  245. func (ipv4 IPv4Addr) DialPacketArgs() (network, dialArgs string) {
  246. if ipv4.Mask != IPv4HostMask || ipv4.Port == 0 {
  247. return "udp4", ""
  248. }
  249. return "udp4", fmt.Sprintf("%s:%d", ipv4.NetIP().String(), ipv4.Port)
  250. }
  251. // DialStreamArgs returns the arguments required to be passed to
  252. // net.DialTCP(). If the Mask of ipv4 is not a /32 or the Port is 0,
  253. // DialStreamArgs() will fail. See Host() to create an IPv4Addr with its
  254. // mask set to /32.
  255. func (ipv4 IPv4Addr) DialStreamArgs() (network, dialArgs string) {
  256. if ipv4.Mask != IPv4HostMask || ipv4.Port == 0 {
  257. return "tcp4", ""
  258. }
  259. return "tcp4", fmt.Sprintf("%s:%d", ipv4.NetIP().String(), ipv4.Port)
  260. }
  261. // Equal returns true if a SockAddr is equal to the receiving IPv4Addr.
  262. func (ipv4 IPv4Addr) Equal(sa SockAddr) bool {
  263. ipv4b, ok := sa.(IPv4Addr)
  264. if !ok {
  265. return false
  266. }
  267. if ipv4.Port != ipv4b.Port {
  268. return false
  269. }
  270. if ipv4.Address != ipv4b.Address {
  271. return false
  272. }
  273. if ipv4.NetIPNet().String() != ipv4b.NetIPNet().String() {
  274. return false
  275. }
  276. return true
  277. }
  278. // FirstUsable returns an IPv4Addr set to the first address following the
  279. // network prefix. The first usable address in a network is normally the
  280. // gateway and should not be used except by devices forwarding packets
  281. // between two administratively distinct networks (i.e. a router). This
  282. // function does not discriminate against first usable vs "first address that
  283. // should be used." For example, FirstUsable() on "192.168.1.10/24" would
  284. // return the address "192.168.1.1/24".
  285. func (ipv4 IPv4Addr) FirstUsable() IPAddr {
  286. addr := ipv4.NetworkAddress()
  287. // If /32, return the address itself. If /31 assume a point-to-point
  288. // link and return the lower address.
  289. if ipv4.Maskbits() < 31 {
  290. addr++
  291. }
  292. return IPv4Addr{
  293. Address: IPv4Address(addr),
  294. Mask: IPv4HostMask,
  295. }
  296. }
  297. // Host returns a copy of ipv4 with its mask set to /32 so that it can be
  298. // used by DialPacketArgs(), DialStreamArgs(), ListenPacketArgs(), or
  299. // ListenStreamArgs().
  300. func (ipv4 IPv4Addr) Host() IPAddr {
  301. // Nothing should listen on a broadcast address.
  302. return IPv4Addr{
  303. Address: ipv4.Address,
  304. Mask: IPv4HostMask,
  305. Port: ipv4.Port,
  306. }
  307. }
  308. // IPPort returns the Port number attached to the IPv4Addr
  309. func (ipv4 IPv4Addr) IPPort() IPPort {
  310. return ipv4.Port
  311. }
  312. // LastUsable returns the last address before the broadcast address in a
  313. // given network.
  314. func (ipv4 IPv4Addr) LastUsable() IPAddr {
  315. addr := ipv4.BroadcastAddress()
  316. // If /32, return the address itself. If /31 assume a point-to-point
  317. // link and return the upper address.
  318. if ipv4.Maskbits() < 31 {
  319. addr--
  320. }
  321. return IPv4Addr{
  322. Address: IPv4Address(addr),
  323. Mask: IPv4HostMask,
  324. }
  325. }
  326. // ListenPacketArgs returns the arguments required to be passed to
  327. // net.ListenUDP(). If the Mask of ipv4 is not a /32, ListenPacketArgs()
  328. // will fail. See Host() to create an IPv4Addr with its mask set to /32.
  329. func (ipv4 IPv4Addr) ListenPacketArgs() (network, listenArgs string) {
  330. if ipv4.Mask != IPv4HostMask {
  331. return "udp4", ""
  332. }
  333. return "udp4", fmt.Sprintf("%s:%d", ipv4.NetIP().String(), ipv4.Port)
  334. }
  335. // ListenStreamArgs returns the arguments required to be passed to
  336. // net.ListenTCP(). If the Mask of ipv4 is not a /32, ListenStreamArgs()
  337. // will fail. See Host() to create an IPv4Addr with its mask set to /32.
  338. func (ipv4 IPv4Addr) ListenStreamArgs() (network, listenArgs string) {
  339. if ipv4.Mask != IPv4HostMask {
  340. return "tcp4", ""
  341. }
  342. return "tcp4", fmt.Sprintf("%s:%d", ipv4.NetIP().String(), ipv4.Port)
  343. }
  344. // Maskbits returns the number of network mask bits in a given IPv4Addr. For
  345. // example, the Maskbits() of "192.168.1.1/24" would return 24.
  346. func (ipv4 IPv4Addr) Maskbits() int {
  347. mask := make(net.IPMask, IPv4len)
  348. binary.BigEndian.PutUint32(mask, uint32(ipv4.Mask))
  349. maskOnes, _ := mask.Size()
  350. return maskOnes
  351. }
  352. // MustIPv4Addr is a helper method that must return an IPv4Addr or panic on
  353. // invalid input.
  354. func MustIPv4Addr(addr string) IPv4Addr {
  355. ipv4, err := NewIPv4Addr(addr)
  356. if err != nil {
  357. panic(fmt.Sprintf("Unable to create an IPv4Addr from %+q: %v", addr, err))
  358. }
  359. return ipv4
  360. }
  361. // NetIP returns the address as a net.IP (address is always presized to
  362. // IPv4).
  363. func (ipv4 IPv4Addr) NetIP() *net.IP {
  364. x := make(net.IP, IPv4len)
  365. binary.BigEndian.PutUint32(x, uint32(ipv4.Address))
  366. return &x
  367. }
  368. // NetIPMask create a new net.IPMask from the IPv4Addr.
  369. func (ipv4 IPv4Addr) NetIPMask() *net.IPMask {
  370. ipv4Mask := net.IPMask{}
  371. ipv4Mask = make(net.IPMask, IPv4len)
  372. binary.BigEndian.PutUint32(ipv4Mask, uint32(ipv4.Mask))
  373. return &ipv4Mask
  374. }
  375. // NetIPNet create a new net.IPNet from the IPv4Addr.
  376. func (ipv4 IPv4Addr) NetIPNet() *net.IPNet {
  377. ipv4net := &net.IPNet{}
  378. ipv4net.IP = make(net.IP, IPv4len)
  379. binary.BigEndian.PutUint32(ipv4net.IP, uint32(ipv4.NetworkAddress()))
  380. ipv4net.Mask = *ipv4.NetIPMask()
  381. return ipv4net
  382. }
  383. // Network returns the network prefix or network address for a given network.
  384. func (ipv4 IPv4Addr) Network() IPAddr {
  385. return IPv4Addr{
  386. Address: IPv4Address(ipv4.NetworkAddress()),
  387. Mask: ipv4.Mask,
  388. }
  389. }
  390. // NetworkAddress returns an IPv4Network of the IPv4Addr's network address.
  391. func (ipv4 IPv4Addr) NetworkAddress() IPv4Network {
  392. return IPv4Network(uint32(ipv4.Address) & uint32(ipv4.Mask))
  393. }
  394. // Octets returns a slice of the four octets in an IPv4Addr's Address. The
  395. // order of the bytes is big endian.
  396. func (ipv4 IPv4Addr) Octets() []int {
  397. return []int{
  398. int(ipv4.Address >> 24),
  399. int((ipv4.Address >> 16) & 0xff),
  400. int((ipv4.Address >> 8) & 0xff),
  401. int(ipv4.Address & 0xff),
  402. }
  403. }
  404. // String returns a string representation of the IPv4Addr
  405. func (ipv4 IPv4Addr) String() string {
  406. if ipv4.Port != 0 {
  407. return fmt.Sprintf("%s:%d", ipv4.NetIP().String(), ipv4.Port)
  408. }
  409. if ipv4.Maskbits() == 32 {
  410. return ipv4.NetIP().String()
  411. }
  412. return fmt.Sprintf("%s/%d", ipv4.NetIP().String(), ipv4.Maskbits())
  413. }
  414. // Type is used as a type switch and returns TypeIPv4
  415. func (IPv4Addr) Type() SockAddrType {
  416. return TypeIPv4
  417. }
  418. // IPv4AddrAttr returns a string representation of an attribute for the given
  419. // IPv4Addr.
  420. func IPv4AddrAttr(ipv4 IPv4Addr, selector AttrName) string {
  421. fn, found := ipv4AddrAttrMap[selector]
  422. if !found {
  423. return ""
  424. }
  425. return fn(ipv4)
  426. }
  427. // IPv4Attrs returns a list of attributes supported by the IPv4Addr type
  428. func IPv4Attrs() []AttrName {
  429. return ipv4AddrAttrs
  430. }
  431. // ipv4AddrInit is called once at init()
  432. func ipv4AddrInit() {
  433. // Sorted for human readability
  434. ipv4AddrAttrs = []AttrName{
  435. "size", // Same position as in IPv6 for output consistency
  436. "broadcast",
  437. "uint32",
  438. }
  439. ipv4AddrAttrMap = map[AttrName]func(ipv4 IPv4Addr) string{
  440. "broadcast": func(ipv4 IPv4Addr) string {
  441. return ipv4.Broadcast().String()
  442. },
  443. "size": func(ipv4 IPv4Addr) string {
  444. return fmt.Sprintf("%d", 1<<uint(IPv4len*8-ipv4.Maskbits()))
  445. },
  446. "uint32": func(ipv4 IPv4Addr) string {
  447. return fmt.Sprintf("%d", uint32(ipv4.Address))
  448. },
  449. }
  450. }