Skip to content

Commit

Permalink
change network configuration to read it from the hypervisor
Browse files Browse the repository at this point in the history
  • Loading branch information
mhewedy committed Nov 23, 2020
1 parent 65a71a8 commit 16a81d0
Show file tree
Hide file tree
Showing 8 changed files with 183 additions and 114 deletions.
66 changes: 66 additions & 0 deletions hypervisor/base/types.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
package base

import (
"encoding/binary"
"fmt"
"math"
"net"
)

type Hypervisor interface {
Start(vmName string) error

Expand All @@ -26,6 +33,8 @@ type Hypervisor interface {
SetNetworkAdapterAsBridge(vmName string) error

GetBoxInfo(vmName string) (*Box, error)

GetSubnet() (*Subnet, error)
}

type MountPath struct {
Expand All @@ -39,3 +48,60 @@ type Box struct {
DiskSize string
MACAddr string
}

type Subnet struct {
start uint32 // start ip address in the subnet in int32 representation
current uint32 // holds the int32 of ip, used to increment by 1 in next method
Len int // length of ips in the subnet
}

// anIp is some ip inside the subnet
func NewSubnet(anIp, netmask string) (*Subnet, error) {

ones, bits := net.IPMask(net.ParseIP(netmask).To4()).Size()
_, ipNet, err := net.ParseCIDR(fmt.Sprintf("%s/%d", anIp, ones))
if err != nil {
return nil, err
}

ipAddr := ip2int(ipNet.IP)
l := int(math.Pow(2, float64(bits-ones)) - 1)
return &Subnet{
start: ipAddr,
current: ipAddr,
Len: l,
}, nil
}

func (c *Subnet) HasNext() bool {
max := c.start + uint32(c.Len)
if c.current < max {
return true
}
return false
}

func (c *Subnet) Next() *Subnet {
return &Subnet{
start: c.start,
current: c.current + 1,
Len: c.Len,
}
}

func (c *Subnet) IP() string {
return int2ip(c.current)
}

func ip2int(ip net.IP) uint32 {
if len(ip) == 16 {
return binary.BigEndian.Uint32(ip[12:16])
}
return binary.BigEndian.Uint32(ip)
}

func int2ip(nn uint32) string {
ip := make(net.IP, 4)
binary.BigEndian.PutUint32(ip, nn)
return ip.String()
}
45 changes: 45 additions & 0 deletions hypervisor/base/types_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package base

import (
"reflect"
"testing"
)

// extract test data using: https://www.ipaddressguide.com/cidr
func TestNewSubnet(t *testing.T) {
type args struct {
anIp string
netmask string
}
tests := []struct {
name string
args args
want *Subnet
wantErr bool
}{
{
name: "test subnet 192.168",
args: args{anIp: "192.168.100.4", netmask: "255.255.255.0"},
want: &Subnet{start: 3232261120, current: 3232261120, Len: 255},
wantErr: false,
},
{
name: "test subnet 172.31 with /20 cidr",
args: args{anIp: "172.31.17.69", netmask: "255.255.240.0"},
want: &Subnet{start: 2887716864, current: 2887716864, Len: 4095},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := NewSubnet(tt.args.anIp, tt.args.netmask)
if (err != nil) != tt.wantErr {
t.Errorf("NewSubnet() error = %v, wantErr %v", err, tt.wantErr)
return
}
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewSubnet() = %v, want %v", got, tt.want)
}
})
}
}
9 changes: 9 additions & 0 deletions hypervisor/hypervisor.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,3 +150,12 @@ func GetBoxInfo(vmName string) (*base.Box, error) {

return h.GetBoxInfo(vmName)
}

func GetSubnet() (*base.Subnet, error) {
h, err := detect()
if err != nil {
return nil, err
}

return h.GetSubnet()
}
33 changes: 33 additions & 0 deletions hypervisor/virtualbox/bridgedifs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package virtualbox

import (
"strings"
)

func findBridgeInfo(keys ...string) ([]string, error) {

r, err := vboxManage("list", "bridgedifs").Call()
if err != nil {
return nil, err
}

list := strings.Split(r, "\n\n")[0]
lines := strings.Split(list, "\n")

elements := make(map[string]string)

for _, line := range lines {
s := strings.SplitN(line, ":", 2)

key := strings.TrimSpace(s[0])
value := strings.TrimSpace(s[1])
elements[key] = value
}

var ret = make([]string, len(keys))
for i, key := range keys {
ret[i] = elements[key]
}

return ret, nil
}
10 changes: 10 additions & 0 deletions hypervisor/virtualbox/virtualbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -233,3 +233,13 @@ func (*virtualbox) SetNetworkAdapterAsBridge(vmName string) error {
func (*virtualbox) GetBoxInfo(vmName string) (*base.Box, error) {
return getBoxInfo(vmName)
}

func (*virtualbox) GetSubnet() (*base.Subnet, error) {

bridgeInfo, err := findBridgeInfo("IPAddress", "NetworkMask")
if err != nil {
return nil, err
}

return base.NewSubnet(bridgeInfo[0], bridgeInfo[1])
}
82 changes: 0 additions & 82 deletions ip/cidr.go

This file was deleted.

8 changes: 6 additions & 2 deletions ip/ip.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@ func Find(vmName string, purge bool) (string, error) {

if purge {
debug.Log("purge=1, purging...")
ping()
if err := ping(); err != nil {
return "", err
}
pong = true
}

Expand All @@ -54,7 +56,9 @@ func Find(vmName string, purge bool) (string, error) {
break
}

ping()
if err := ping(); err != nil {
return "", err
}
pong = true
}

Expand Down
44 changes: 14 additions & 30 deletions ip/ping.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,32 @@ package ip
import (
"github.com/mhewedy/vermin/cmd"
"github.com/mhewedy/vermin/debug"
"github.com/mhewedy/vermin/hypervisor"
"github.com/mhewedy/vermin/hypervisor/base"
"sync"
)

func ping() {
func ping() error {

cidrs := getCIDRs()
debug.Log("ciders: %s", cidrs)

var wg sync.WaitGroup
wg.Add(len(cidrs))

for _, c := range cidrs {

if c.len > 65535 { // skipping cidrs with len > x.x.x.x/16 including 127.0.0.0/8
wg.Done()
continue
}

debug.Log("pining cider %s", c)
go func(c cidr) {
pingCIDR(c)
wg.Done()
}(c)
subnet, err := hypervisor.GetSubnet()
if err != nil {
return err
}

wg.Wait()
}

func pingCIDR(c cidr) {
debug.Log("subnet: %v", subnet)

var wg sync.WaitGroup
wg.Add(c.len)
wg.Add(subnet.Len)

for c.hasNext() {
c = c.next()
for subnet.HasNext() {
subnet = subnet.Next()

go func(cc cidr) {
_ = cmd.Ping(cc.IP()).Run()
go func(s *base.Subnet) {
_ = cmd.Ping(s.IP()).Run()
wg.Done()
}(c)
}(subnet)
}

wg.Wait()

return nil
}

0 comments on commit 16a81d0

Please sign in to comment.