ZeroTierOne/go/pkg/zerotier/address.go
2019-09-22 17:41:15 -07:00

66 lines
1.7 KiB
Go

/*
* Copyright (c)2019 ZeroTier, Inc.
*
* Use of this software is governed by the Business Source License included
* in the LICENSE.TXT file in the project's root directory.
*
* Change Date: 2023-01-01
*
* On the date above, in accordance with the Business Source License, use
* of this software will be governed by version 2.0 of the Apache License.
*/
/****/
package zerotier
import (
"encoding/json"
"fmt"
"strconv"
)
// Address represents a 40-bit short ZeroTier address
type Address uint64
// NewAddressFromString parses a 10-digit ZeroTier address
func NewAddressFromString(s string) (Address, error) {
if len(s) != 10 {
return Address(0), ErrInvalidZeroTierAddress
}
a, err := strconv.ParseUint(s, 16, 64)
return Address(a & 0xffffffffff), err
}
// NewAddressFromBytes reads a 5-byte 40-bit address.
func NewAddressFromBytes(b []byte) (Address, error) {
if len(b) < 5 {
return Address(0), ErrInvalidZeroTierAddress
}
return Address((uint64(b[0]) << 32) | (uint64(b[1]) << 24) | (uint64(b[2]) << 16) | (uint64(b[3]) << 8) | uint64(b[4])), nil
}
// IsReserved returns true if this address is reserved and therefore is not valid for a real node.
func (a Address) IsReserved() bool { return a == 0 || (a>>32) == 0xff }
// String returns this address's 10-digit hex identifier
func (a Address) String() string {
return fmt.Sprintf("%.10x", uint64(a))
}
// MarshalJSON marshals this Address as a string
func (a Address) MarshalJSON() ([]byte, error) {
return []byte("\"" + a.String() + "\""), nil
}
// UnmarshalJSON unmarshals this Address from a string
func (a *Address) UnmarshalJSON(j []byte) error {
var s string
err := json.Unmarshal(j, &s)
if err != nil {
return err
}
tmp, err := NewAddressFromString(s)
*a = tmp
return err
}