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

Basics

parent 8092e1d8
No related branches found
No related tags found
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,
}
}
......@@ -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