diff --git a/net/ip.go b/net/ip.go index f1d80fcd473ffb94fb0898733e38ad92c32e69af..143505ca49eb2d2868bc31ce4fee04b1a26ff3aa 100644 --- a/net/ip.go +++ b/net/ip.go @@ -19,6 +19,11 @@ func IPv4(val uint32) IP { } } +// IPv4FromOctets returns an IPv4 address for the given 4 octets +func IPv4FromOctets(o1, o2, o3, o4 uint8) IP { + return IPv4(uint32(o1)<<24 + uint32(o2)<<16 + uint32(o3)<<8 + uint32(o4)) +} + // IPv6 returns a new `IP` representing an IPv6 address func IPv6(higher, lower uint64) IP { return IP{ @@ -28,6 +33,13 @@ func IPv6(higher, lower uint64) IP { } } +// IPv6FromBlocks returns an IPv6 address for the given 8 blocks +func IPv6FromBlocks(b1, b2, b3, b4, b5, b6, b7, b8 uint16) IP { + return IPv6( + uint64(uint64(b1)<<48+uint64(b2)<<32+uint64(b3)<<16+uint64(b4)), + uint64(uint64(b5)<<48+uint64(b6)<<32+uint64(b7)<<16+uint64(b8))) +} + // ToUint32 returns the uint32 representation of an IP address func (ip *IP) ToUint32() uint32 { return uint32(^uint64(0) >> 32 & ip.lower) @@ -77,15 +89,47 @@ func (ip IP) stringIPv6() string { } func (ip IP) stringIPv4() string { - u := ip.ToUint32() + b := ip.Bytes() + + return fmt.Sprintf("%d.%d.%d.%d", b[0], b[1], b[2], b[3]) +} - return fmt.Sprintf("%d.%d.%d.%d", - u&0xFF000000>>24, - u&0x00FF0000>>16, - u&0x0000FF00>>8, - u&0x000000FF) +// Bytes returns the byte representation of an IP address +func (ip IP) Bytes() []byte { + if ip.ipVersion == 6 { + return ip.bytesIPv6() + } + + return ip.bytesIPv4() } -func (ip IP) Bytes() { +func (ip IP) bytesIPv4() []byte { + u := ip.ToUint32() + return []byte{ + byte(u & 0xFF000000 >> 24), + byte(u & 0x00FF0000 >> 16), + byte(u & 0x0000FF00 >> 8), + byte(u & 0x000000FF), + } +} +func (ip IP) bytesIPv6() []byte { + return []byte{ + byte(ip.higher & 0xFF00000000000000 >> 56), + byte(ip.higher & 0x00FF000000000000 >> 48), + byte(ip.higher & 0x0000FF0000000000 >> 40), + byte(ip.higher & 0x000000FF00000000 >> 32), + byte(ip.higher & 0x00000000FF000000 >> 24), + byte(ip.higher & 0x0000000000FF0000 >> 16), + byte(ip.higher & 0x000000000000FF00 >> 8), + byte(ip.higher & 0x00000000000000FF), + byte(ip.lower & 0xFF00000000000000 >> 56), + byte(ip.lower & 0x00FF000000000000 >> 48), + byte(ip.lower & 0x0000FF0000000000 >> 40), + byte(ip.lower & 0x000000FF00000000 >> 32), + byte(ip.lower & 0x00000000FF000000 >> 24), + byte(ip.lower & 0x0000000000FF0000 >> 16), + byte(ip.lower & 0x000000000000FF00 >> 8), + byte(ip.lower & 0x00000000000000FF), + } } diff --git a/net/ip_test.go b/net/ip_test.go index ab8bfcd7b757a810993f3ee40e7279cc32c675ce..c6358d069b287bc539aab07fb837772ff95787c2 100644 --- a/net/ip_test.go +++ b/net/ip_test.go @@ -1,6 +1,7 @@ package net import ( + "math" "testing" "github.com/stretchr/testify/assert" @@ -145,3 +146,111 @@ func TestIPString(t *testing.T) { assert.Equal(t, test.expected, test.ip.String()) } } + +func TestBytes(t *testing.T) { + tests := []struct { + name string + ip IP + expected []byte + }{ + { + name: "IPv4 172.217.16.195", + ip: IPv4(2899906755), + expected: []byte{172, 217, 16, 195}, + }, + { + name: "IPv6 2001:678:1E0:1234:5678:DEAD:BEEF:CAFE", + ip: IPv6(2306131596687708724, 6230974922281175806), + expected: []byte{32, 1, 6, 120, 1, 224, 18, 52, 86, 120, 222, 173, 190, 239, 202, 254}, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, test.ip.Bytes()) + }) + } +} + +func TestIPv4FromOctets(t *testing.T) { + tests := []struct { + name string + octets []uint8 + expected IP + }{ + { + name: "172.217.16.195", + octets: []uint8{172, 217, 16, 195}, + expected: IP{ + higher: 0, + lower: 2899906755, + ipVersion: 4, + }, + }, + { + name: "0.0.0.0", + octets: []uint8{0, 0, 0, 0}, + expected: IP{ + higher: 0, + lower: 0, + ipVersion: 4, + }, + }, + { + name: "255.255.255.255", + octets: []uint8{255, 255, 255, 255}, + expected: IP{ + higher: 0, + lower: math.MaxUint32, + ipVersion: 4, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, IPv4FromOctets(test.octets[0], test.octets[1], test.octets[2], test.octets[3])) + }) + } +} + +func TestIPv6FromBlocks(t *testing.T) { + tests := []struct { + name string + blocks []uint16 + expected IP + }{ + { + name: "IPv6 2001:678:1E0:1234:5678:DEAD:BEEF:CAFE", + blocks: []uint16{ + 0x2001, + 0x678, + 0x1e0, + 0x1234, + 0x5678, + 0xdead, + 0xbeef, + 0xcafe, + }, + expected: IP{ + higher: 2306131596687708724, + lower: 6230974922281175806, + ipVersion: 6, + }, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + assert.Equal(t, test.expected, IPv6FromBlocks( + test.blocks[0], + test.blocks[1], + test.blocks[2], + test.blocks[3], + test.blocks[4], + test.blocks[5], + test.blocks[6], + test.blocks[7])) + }) + } +} diff --git a/protocols/bgp/packet/decoder_test.go b/protocols/bgp/packet/decoder_test.go index 64c5cf0426596a04ce463fdfc38b7fb4d8511b87..f7487ccbd61961c933f9ba310d578877b83ae76c 100644 --- a/protocols/bgp/packet/decoder_test.go +++ b/protocols/bgp/packet/decoder_test.go @@ -10,6 +10,8 @@ import ( "github.com/bio-routing/bio-rd/protocols/bgp/types" "github.com/stretchr/testify/assert" "github.com/taktv6/tflow2/convert" + + bnet "github.com/bio-routing/bio-rd/net" ) type test struct { @@ -723,7 +725,7 @@ func TestDecodeUpdateMsg(t *testing.T) { ExtendedLength: false, Length: 4, TypeCode: 3, - Value: strAddr("10.11.12.13"), + Value: bnet.IPv4FromOctets(10, 11, 12, 13), }, }, }, @@ -813,7 +815,7 @@ func TestDecodeUpdateMsg(t *testing.T) { ExtendedLength: false, Length: 4, TypeCode: 3, - Value: strAddr("10.11.12.13"), + Value: bnet.IPv4FromOctets(10, 11, 12, 13), Next: &PathAttribute{ Optional: false, Transitive: false, @@ -916,7 +918,7 @@ func TestDecodeUpdateMsg(t *testing.T) { ExtendedLength: false, Length: 4, TypeCode: 3, - Value: strAddr("10.11.12.13"), + Value: bnet.IPv4FromOctets(10, 11, 12, 13), Next: &PathAttribute{ Optional: false, Transitive: false, @@ -1032,7 +1034,7 @@ func TestDecodeUpdateMsg(t *testing.T) { ExtendedLength: false, Length: 4, TypeCode: 3, - Value: strAddr("10.11.12.13"), + Value: bnet.IPv4FromOctets(10, 11, 12, 13), Next: &PathAttribute{ Optional: false, Transitive: false, @@ -1164,7 +1166,7 @@ func TestDecodeUpdateMsg(t *testing.T) { ExtendedLength: false, Length: 4, TypeCode: 3, - Value: strAddr("10.11.12.13"), + Value: bnet.IPv4FromOctets(10, 11, 12, 13), Next: &PathAttribute{ Optional: false, Transitive: false, diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go index 000f0d8e95fe82ca67c8d57e9601dc090e58ca6f..32569f4202901bae70847a99e4da1d39e6b46fc0 100644 --- a/protocols/bgp/packet/path_attributes.go +++ b/protocols/bgp/packet/path_attributes.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/protocols/bgp/types" "github.com/bio-routing/bio-rd/route" "github.com/taktv6/tflow2/convert" @@ -211,7 +212,14 @@ func (pa *PathAttribute) decode2ByteASN(buf *bytes.Buffer) (asn uint32, err erro } func (pa *PathAttribute) decodeNextHop(buf *bytes.Buffer) error { - return pa.decodeUint32(buf, "next hop") + nextHop := uint32(0) + err := decode(buf, []interface{}{&nextHop}) + if err != nil { + return fmt.Errorf("Unable to decode next hop: %v", err) + } + + pa.Value = bnet.IPv4(nextHop) + return nil } func (pa *PathAttribute) decodeMED(buf *bytes.Buffer) error { @@ -453,8 +461,8 @@ func (pa *PathAttribute) serializeNextHop(buf *bytes.Buffer) uint8 { buf.WriteByte(NextHopAttr) length := uint8(4) buf.WriteByte(length) - addr := pa.Value.(uint32) - buf.Write(convert.Uint32Byte(addr)) + addr := pa.Value.(bnet.IP) + buf.Write(addr.Bytes()) return 7 } diff --git a/protocols/bgp/packet/path_attributes_test.go b/protocols/bgp/packet/path_attributes_test.go index 93a0b2e515f0dfb9f0a0dde543085a37fb3c52c3..aa3f319a06599e57aee477b28f1310222303eb1c 100644 --- a/protocols/bgp/packet/path_attributes_test.go +++ b/protocols/bgp/packet/path_attributes_test.go @@ -4,6 +4,7 @@ import ( "bytes" "testing" + bnet "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/protocols/bgp/types" "github.com/stretchr/testify/assert" ) @@ -35,7 +36,7 @@ func TestDecodePathAttrs(t *testing.T) { Next: &PathAttribute{ TypeCode: 3, Length: 4, - Value: strAddr("10.20.30.40"), + Value: bnet.IPv4FromOctets(10, 20, 30, 40), }, }, }, @@ -396,7 +397,7 @@ func TestDecodeNextHop(t *testing.T) { wantFail: false, expected: &PathAttribute{ Length: 4, - Value: strAddr("10.20.30.40"), + Value: bnet.IPv4FromOctets(10, 20, 30, 40), }, }, { @@ -1004,7 +1005,7 @@ func TestSerializeNextHop(t *testing.T) { name: "Test #1", input: &PathAttribute{ TypeCode: NextHopAttr, - Value: strAddr("100.110.120.130"), + Value: bnet.IPv4FromOctets(100, 110, 120, 130), }, expected: []byte{64, 3, 4, 100, 110, 120, 130}, expectedLen: 7, @@ -1499,7 +1500,7 @@ func TestSerialize(t *testing.T) { }, Next: &PathAttribute{ TypeCode: NextHopAttr, - Value: strAddr("10.20.30.40"), + Value: bnet.IPv4FromOctets(10, 20, 30, 40), Next: &PathAttribute{ TypeCode: MEDAttr, Value: uint32(100), @@ -1704,7 +1705,7 @@ func TestSerializeAddPath(t *testing.T) { }, Next: &PathAttribute{ TypeCode: NextHopAttr, - Value: strAddr("10.20.30.40"), + Value: bnet.IPv4FromOctets(10, 20, 30, 40), Next: &PathAttribute{ TypeCode: MEDAttr, Value: uint32(100), diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go index 20ae668232984fead709cbfae9cceeecfec97217..feaf1ee14badba4dae6ff8648a9308380c7db92a 100644 --- a/protocols/bgp/server/fsm_established.go +++ b/protocols/bgp/server/fsm_established.go @@ -73,11 +73,11 @@ func (s *establishedState) init() error { n := &routingtable.Neighbor{ Type: route.BGPPathType, - Address: bnet.IPv4ToUint32(s.fsm.peer.addr), + Address: bnet.IPv4(bnet.IPv4ToUint32(s.fsm.peer.addr)), IBGP: s.fsm.peer.localASN == s.fsm.peer.peerASN, LocalASN: s.fsm.peer.localASN, RouteServerClient: s.fsm.peer.routeServerClient, - LocalAddress: bnet.IPv4ToUint32(hostIP), + LocalAddress: bnet.IPv4(bnet.IPv4ToUint32(hostIP)), CapAddPathRX: s.fsm.options.AddPathRX, } @@ -219,7 +219,7 @@ func (s *establishedState) updates(u *packet.BGPUpdate) { path := &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ - Source: bnet.IPv4ToUint32(s.fsm.peer.addr), + Source: bnet.IPv4(bnet.IPv4ToUint32(s.fsm.peer.addr)), EBGP: s.fsm.peer.localASN != s.fsm.peer.peerASN, }, } @@ -240,7 +240,7 @@ func (s *establishedState) processAttributes(attrs *packet.PathAttribute, path * case packet.MEDAttr: path.BGPPath.MED = pa.Value.(uint32) case packet.NextHopAttr: - path.BGPPath.NextHop = pa.Value.(uint32) + path.BGPPath.NextHop = pa.Value.(bnet.IP) case packet.ASPathAttr: path.BGPPath.ASPath = pa.Value.(types.ASPath) path.BGPPath.ASPathLen = path.BGPPath.ASPath.Length() diff --git a/route/bgp_path.go b/route/bgp_path.go index 4eec57b3326b968a221f79c0359cfdcf73ba95c0..1ea90b4e76506a2f5144c21a817040e42b88dcfe 100644 --- a/route/bgp_path.go +++ b/route/bgp_path.go @@ -210,12 +210,10 @@ func (b *BGPPath) Print() string { ret += fmt.Sprintf("\t\tOrigin: %s\n", origin) ret += fmt.Sprintf("\t\tAS Path: %v\n", b.ASPath) ret += fmt.Sprintf("\t\tBGP type: %s\n", bgpType) - nh := uint32To4Byte(b.NextHop.ToUint32()) - ret += fmt.Sprintf("\t\tNEXT HOP: %d.%d.%d.%d\n", nh[0], nh[1], nh[2], nh[3]) + ret += fmt.Sprintf("\t\tNEXT HOP: %s\n", b.NextHop) ret += fmt.Sprintf("\t\tMED: %d\n", b.MED) ret += fmt.Sprintf("\t\tPath ID: %d\n", b.PathIdentifier) - src := uint32To4Byte(b.Source) - ret += fmt.Sprintf("\t\tSource: %d.%d.%d.%d\n", src[0], src[1], src[2], src[3]) + ret += fmt.Sprintf("\t\tSource: %s\n", b.Source) ret += fmt.Sprintf("\t\tCommunities: %v\n", b.Communities) ret += fmt.Sprintf("\t\tLargeCommunities: %v\n", b.LargeCommunities) @@ -285,7 +283,7 @@ func (b *BGPPath) Copy() *BGPPath { // ComputeHash computes an hash over all attributes of the path func (b *BGPPath) ComputeHash() string { - s := fmt.Sprintf("%d\t%d\t%v\t%d\t%d\t%v\t%d\t%d\t%v\t%v\t%d", + s := fmt.Sprintf("%s\t%d\t%v\t%d\t%d\t%v\t%d\t%s\t%v\t%v\t%d", b.NextHop, b.LocalPref, b.ASPath, diff --git a/route/bgp_test.go b/route/bgp_test.go index 46ceb9af2364746aba48711400e9091cc882457f..f399d5d51ab96ad1a5b789a22aceb4d7b2490932 100644 --- a/route/bgp_test.go +++ b/route/bgp_test.go @@ -5,6 +5,8 @@ import ( "github.com/bio-routing/bio-rd/protocols/bgp/types" "github.com/stretchr/testify/assert" + + bnet "github.com/bio-routing/bio-rd/net" ) func TestComputeHash(t *testing.T) { @@ -29,14 +31,14 @@ func TestComputeHash(t *testing.T) { }, LocalPref: 100, MED: 1, - NextHop: 100, + NextHop: bnet.IPv4(100), PathIdentifier: 5, - Source: 4, + Source: bnet.IPv4(4), } - assert.Equal(t, "45e238420552b88043edb8cb402034466b08d53b49f8e0fedc680747014ddeff", p.ComputeHash()) + assert.Equal(t, "98d68e69d993f8807c561cc7d63de759f7edc732887f88a7ebf42f61b9e54821", p.ComputeHash()) p.LocalPref = 150 - assert.NotEqual(t, "45e238420552b88043edb8cb402034466b08d53b49f8e0fedc680747014ddeff", p.ComputeHash()) + assert.NotEqual(t, "98d68e69d993f8807c561cc7d63de759f7edc732887f88a7ebf42f61b9e54821", p.ComputeHash()) } diff --git a/routingtable/filter/actions/set_nexthop_action_test.go b/routingtable/filter/actions/set_nexthop_action_test.go index 7501e6bdcc388c65577cea8ce0a425acf8b7d3e3..269970adbc33d0b3a39375acc966f49e0927e3ab 100644 --- a/routingtable/filter/actions/set_nexthop_action_test.go +++ b/routingtable/filter/actions/set_nexthop_action_test.go @@ -6,13 +6,15 @@ import ( "github.com/bio-routing/bio-rd/net" "github.com/bio-routing/bio-rd/route" "github.com/stretchr/testify/assert" + + bnet "github.com/bio-routing/bio-rd/net" ) func TestSetNextHopTest(t *testing.T) { tests := []struct { name string bgpPath *route.BGPPath - expected uint32 + expected net.IP }{ { name: "BGPPath is nil", @@ -20,21 +22,21 @@ func TestSetNextHopTest(t *testing.T) { { name: "modify path", bgpPath: &route.BGPPath{ - NextHop: strAddr("100.64.2.1"), + NextHop: bnet.IPv4FromOctets(192, 168, 1, 1), }, - expected: strAddr("100.64.2.1"), + expected: bnet.IPv4FromOctets(100, 64, 2, 1), }, } for _, test := range tests { - t.Run(test.name, func(te *testing.T) { - a := NewSetNextHopAction(strAddr("100.64.2.1")) + t.Run(test.name, func(t *testing.T) { + a := NewSetNextHopAction(bnet.IPv4FromOctets(100, 64, 2, 1)) p, _ := a.Do(net.NewPfx(strAddr("10.0.0.0"), 8), &route.Path{ BGPPath: test.bgpPath, }) - if test.expected > 0 { - assert.Equal(te, test.expected, p.BGPPath.NextHop) + if test.bgpPath != nil { + assert.Equal(t, test.expected, p.BGPPath.NextHop) } }) } diff --git a/routingtable/table_test.go b/routingtable/table_test.go index ef18c5175533a649504f4d6ade2a43edcda102ff..acc5373857e2a202a6874a7d39331edbad430fab 100644 --- a/routingtable/table_test.go +++ b/routingtable/table_test.go @@ -482,14 +482,14 @@ func TestReplacePath(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1001, - NextHop: 101, + NextHop: net.IPv4(101), }, }), route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -511,13 +511,13 @@ func TestReplacePath(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1001, - NextHop: 101, + NextHop: net.IPv4(101), }, }, &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -542,14 +542,14 @@ func TestReplacePath(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1001, - NextHop: 101, + NextHop: net.IPv4(101), }, }), route.NewRoute(net.NewPfx(strAddr("11.0.0.0"), 8), &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -571,13 +571,13 @@ func TestReplacePath(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1001, - NextHop: 101, + NextHop: net.IPv4(101), }, }, &route.Path{ Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -642,7 +642,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -659,7 +659,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -679,7 +679,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -696,7 +696,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -716,7 +716,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -733,7 +733,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -758,7 +758,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, @@ -768,7 +768,7 @@ func TestRemovePrefix(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ LocalPref: 1002, - NextHop: 100, + NextHop: net.IPv4(100), }, }), }, diff --git a/routingtable/update_helper_test.go b/routingtable/update_helper_test.go index 451b983beae4df2ce289b60be0be8d1b7bd7f67a..226be1b3c10c9fffe500aa48a1bccc14b018bf62 100644 --- a/routingtable/update_helper_test.go +++ b/routingtable/update_helper_test.go @@ -1,7 +1,6 @@ package routingtable import ( - "net" "strings" "testing" @@ -27,7 +26,7 @@ func TestShouldPropagateUpdate(t *testing.T) { communities: "(1,2)", neighbor: Neighbor{ Type: route.BGPPathType, - Address: bnet.IPv4ToUint32(net.ParseIP("192.168.1.1")), + Address: bnet.IPv4FromOctets(192, 168, 1, 1), }, expected: false, }, @@ -79,7 +78,7 @@ func TestShouldPropagateUpdate(t *testing.T) { Type: route.BGPPathType, BGPPath: &route.BGPPath{ Communities: comms, - Source: bnet.IPv4ToUint32(net.ParseIP("192.168.1.1")), + Source: bnet.IPv4FromOctets(192, 168, 1, 1), }, }