Skip to content
Snippets Groups Projects
Commit de227718 authored by Oliver Herms's avatar Oliver Herms
Browse files

Basics

parent ac09b11f
Branches
Tags
No related merge requests found
......@@ -3,20 +3,55 @@ package net
import (
"fmt"
"net"
"github.com/bio-routing/bio-rd/net/api"
)
// IP represents an IPv4 or IPv6 address
type IP struct {
higher uint64
lower uint64
ipVersion uint8
higher uint64
lower uint64
isLegacy bool
}
// IPFromProtoIP creates an IP address from a proto IP
func IPFromProtoIP(addr api.IP) IP {
return IP{
higher: addr.Higher,
lower: addr.Lower,
isLegacy: addr.IsLegacy,
}
}
// ToProto converts an IP to a proto IP
func (ip IP) ToProto() *api.IP {
return &api.IP{
Lower: ip.lower,
Higher: ip.higher,
IsLegacy: ip.isLegacy,
}
}
// Lower gets the lower half of the IP address
func (ip IP) Lower() uint64 {
return ip.lower
}
// Higher gets the higher half of the IP address
func (ip IP) Higher() uint64 {
return ip.higher
}
// IsLegacy returns true for IPv6, else false
func (ip IP) IsLegacy() bool {
return ip.isLegacy
}
// IPv4 returns a new `IP` representing an IPv4 address
func IPv4(val uint32) IP {
return IP{
lower: uint64(val),
ipVersion: 4,
lower: uint64(val),
isLegacy: true,
}
}
......@@ -28,9 +63,9 @@ func IPv4FromOctets(o1, o2, o3, o4 uint8) IP {
// IPv6 returns a new `IP` representing an IPv6 address
func IPv6(higher, lower uint64) IP {
return IP{
higher: higher,
lower: lower,
ipVersion: 6,
higher: higher,
lower: lower,
isLegacy: false,
}
}
......@@ -59,7 +94,7 @@ func IPFromBytes(b []byte) (IP, error) {
uint16(b[14])<<8+uint16(b[15])), nil
}
return IP{}, fmt.Errorf("byte slice has an invalid legth. Expected either 4 (IPv4) or 16 (IPv6) bytes but got: %d", len(b))
return IP{}, fmt.Errorf("byte slice has an invalid length. Expected either 4 (IPv4) or 16 (IPv6) bytes but got: %d", len(b))
}
// IPFromString returns an IP address for a given string
......@@ -104,7 +139,7 @@ func (ip IP) Compare(other IP) int {
}
func (ip IP) String() string {
if ip.ipVersion == 6 {
if !ip.isLegacy {
return ip.stringIPv6()
}
......@@ -131,7 +166,7 @@ func (ip IP) stringIPv4() string {
// Bytes returns the byte representation of an IP address
func (ip IP) Bytes() []byte {
if ip.ipVersion == 6 {
if !ip.isLegacy {
return ip.bytesIPv6()
}
......@@ -150,12 +185,12 @@ func (ip IP) bytesIPv4() []byte {
// IsIPv4 returns if the `IP` is of address family IPv4
func (ip IP) IsIPv4() bool {
return ip.ipVersion == 4
return ip.isLegacy
}
// SizeBytes returns the number of bytes required to represent the `IP`
func (ip IP) SizeBytes() uint8 {
if ip.ipVersion == 4 {
if ip.isLegacy {
return 4
}
......@@ -195,7 +230,7 @@ func (ip IP) ToNetIP() net.IP {
// BitAtPosition returns the bit at position pos
func (ip IP) BitAtPosition(pos uint8) bool {
if ip.ipVersion == 6 {
if !ip.isLegacy {
return ip.bitAtPositionIPv6(pos)
}
......
......@@ -5,9 +5,88 @@ import (
"net"
"testing"
"github.com/bio-routing/bio-rd/net/api"
"github.com/stretchr/testify/assert"
)
func TestIPToProto(t *testing.T) {
tests := []struct {
name string
ip IP
expected *api.IP
}{
{
name: "IPv4",
ip: IP{
lower: 255,
isLegacy: true,
},
expected: &api.IP{
Lower: 255,
IsLegacy: true,
},
},
{
name: "IPv6",
ip: IP{
higher: 1000,
lower: 255,
isLegacy: false,
},
expected: &api.IP{
Higher: 1000,
Lower: 255,
IsLegacy: false,
},
},
}
for _, test := range tests {
res := test.ip.ToProto()
assert.Equal(t, test.expected, res, test.name)
}
}
func TestIPFromProtoIP(t *testing.T) {
tests := []struct {
name string
proto api.IP
expected IP
}{
{
name: "Test IPv4",
proto: api.IP{
Lower: 100,
Higher: 0,
IsLegacy: true,
},
expected: IP{
lower: 100,
higher: 0,
isLegacy: true,
},
},
{
name: "Test IPv6",
proto: api.IP{
Lower: 100,
Higher: 200,
IsLegacy: false,
},
expected: IP{
lower: 100,
higher: 200,
isLegacy: false,
},
},
}
for _, test := range tests {
res := IPFromProtoIP(test.proto)
assert.Equal(t, test.expected, res, test.name)
}
}
func TestCompare(t *testing.T) {
tests := []struct {
name string
......@@ -155,27 +234,27 @@ func TestIPv4FromOctets(t *testing.T) {
name: "172.217.16.195",
octets: []uint8{172, 217, 16, 195},
expected: IP{
higher: 0,
lower: 2899906755,
ipVersion: 4,
higher: 0,
lower: 2899906755,
isLegacy: true,
},
},
{
name: "0.0.0.0",
octets: []uint8{0, 0, 0, 0},
expected: IP{
higher: 0,
lower: 0,
ipVersion: 4,
higher: 0,
lower: 0,
isLegacy: true,
},
},
{
name: "255.255.255.255",
octets: []uint8{255, 255, 255, 255},
expected: IP{
higher: 0,
lower: math.MaxUint32,
ipVersion: 4,
higher: 0,
lower: math.MaxUint32,
isLegacy: true,
},
},
}
......@@ -206,9 +285,8 @@ func TestIPv6FromBlocks(t *testing.T) {
0xcafe,
},
expected: IP{
higher: 2306131596687708724,
lower: 6230974922281175806,
ipVersion: 6,
higher: 2306131596687708724,
lower: 6230974922281175806,
},
},
}
......@@ -239,18 +317,17 @@ func TestIPFromBytes(t *testing.T) {
name: "IPV4: 172.217.16.195",
bytes: []byte{172, 217, 16, 195},
expected: IP{
higher: 0,
lower: 2899906755,
ipVersion: 4,
higher: 0,
lower: 2899906755,
isLegacy: true,
},
},
{
name: "IPV6: IPv6 2001:678:1E0:1234:5678:DEAD:BEEF:CAFE",
bytes: []byte{0x20, 0x01, 0x06, 0x78, 0x01, 0xE0, 0x12, 0x34, 0x56, 0x78, 0xDE, 0xAD, 0xBE, 0xEF, 0xCA, 0xFE},
expected: IP{
higher: 2306131596687708724,
lower: 6230974922281175806,
ipVersion: 6,
higher: 2306131596687708724,
lower: 6230974922281175806,
},
},
{
......
......@@ -5,6 +5,8 @@ import (
"math"
"strconv"
"strings"
"github.com/bio-routing/bio-rd/net/api"
)
// Prefix represents an IPv4 prefix
......@@ -13,6 +15,22 @@ type Prefix struct {
pfxlen uint8
}
// NewPrefixFromProtoPrefix creates a Prefix from a proto Prefix
func NewPrefixFromProtoPrefix(pfx api.Prefix) Prefix {
return Prefix{
addr: IPFromProtoIP(*pfx.Address),
pfxlen: uint8(pfx.Pfxlen),
}
}
// ToProto converts prefix to proto prefix
func (pfx Prefix) ToProto() api.Prefix {
return api.Prefix{
Address: pfx.addr.ToProto(),
Pfxlen: uint32(pfx.pfxlen),
}
}
// NewPfx creates a new Prefix
func NewPfx(addr IP, pfxlen uint8) Prefix {
return Prefix{
......@@ -66,7 +84,7 @@ func (pfx Prefix) Contains(x Prefix) bool {
return false
}
if pfx.addr.ipVersion == 4 {
if pfx.addr.isLegacy {
return pfx.containsIPv4(x)
}
......@@ -99,7 +117,7 @@ func (pfx Prefix) Equal(x Prefix) bool {
// GetSupernet gets the next common supernet of pfx and x
func (pfx Prefix) GetSupernet(x Prefix) Prefix {
if pfx.addr.ipVersion == 4 {
if pfx.addr.isLegacy {
return pfx.supernetIPv4(x)
}
......
......@@ -3,9 +3,112 @@ package net
import (
"testing"
"github.com/bio-routing/bio-rd/net/api"
"github.com/stretchr/testify/assert"
)
func TestPrefixToProto(t *testing.T) {
tests := []struct {
name string
pfx Prefix
expected api.Prefix
}{
{
name: "IPv4",
pfx: Prefix{
addr: IP{
lower: 200,
isLegacy: true,
},
pfxlen: 24,
},
expected: api.Prefix{
Address: &api.IP{
Lower: 200,
IsLegacy: true,
},
Pfxlen: 24,
},
},
{
name: "IPv6",
pfx: Prefix{
addr: IP{
higher: 100,
lower: 200,
isLegacy: false,
},
pfxlen: 64,
},
expected: api.Prefix{
Address: &api.IP{
Higher: 100,
Lower: 200,
IsLegacy: false,
},
Pfxlen: 64,
},
},
}
for _, test := range tests {
res := test.pfx.ToProto()
assert.Equal(t, test.expected, res, test.name)
}
}
func TestNewPrefixFromProtoPrefix(t *testing.T) {
tests := []struct {
name string
proto api.Prefix
expected Prefix
}{
{
name: "IPv4",
proto: api.Prefix{
Address: &api.IP{
Higher: 0,
Lower: 2000,
IsLegacy: true,
},
Pfxlen: 24,
},
expected: Prefix{
addr: IP{
higher: 0,
lower: 2000,
isLegacy: true,
},
pfxlen: 24,
},
},
{
name: "IPv6",
proto: api.Prefix{
Address: &api.IP{
Higher: 1000,
Lower: 2000,
IsLegacy: false,
},
Pfxlen: 64,
},
expected: Prefix{
addr: IP{
higher: 1000,
lower: 2000,
isLegacy: false,
},
pfxlen: 64,
},
},
}
for _, test := range tests {
res := NewPrefixFromProtoPrefix(test.proto)
assert.Equal(t, test.expected, res, test.name)
}
}
func TestNewPfx(t *testing.T) {
p := NewPfx(IPv4(123), 11)
if p.addr != IPv4(123) || p.pfxlen != 11 {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment