zoreide/interface.go

209 lines
5.1 KiB
Go

package main
import (
"fmt"
"log"
"net"
"time"
"github.com/go-ping/ping"
"github.com/google/uuid"
"github.com/milosgajdos/tenus"
)
func init() {
ZoreideBridge.initializeHierarchy()
}
func (b *AbstractBridge) RefreshArp() {
// we want the program to recover in case of issues
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <RefreshARP()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
b.GArp = new(Gratuitous)
var err error
b.GArp.IP, _, err = net.ParseCIDR(b.BridgeIpCIDR)
if err != nil {
log.Println("Error parsing CIDR: ", err.Error())
}
b.GArp.IfaceName = b.ExistingInterface
log.Println("ARP Interface name: ", b.GArp.IfaceName)
SendGratuitous(b.GArp)
}
func (b *AbstractBridge) initializeHierarchy() {
var err error
var tmpuuid uuid.UUID
tmpuuid, err = uuid.NewRandom()
b.hIerarchyNumber = tmpuuid.String()
if err == nil {
log.Println("Initialized secure host ID: ", b.hIerarchyNumber)
} else {
log.Println("Error happened with random UUID: ", err.Error())
log.Println("Initialized to less secure host ID: ", b.hIerarchyNumber)
b.hIerarchyNumber = uuid.NewString()
}
}
func (b *AbstractBridge) configureIpAndBridgeUp() {
// we want the program to recover in case of issues
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <configureIpAndBridgeUp()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
// first we check the IP is free. Something weird could have happened in some
// other server
brIp, brIpNet, err := net.ParseCIDR(b.BridgeIpCIDR)
if err != nil {
log.Println("Error parsing CIDR: ", err.Error())
}
br, err := tenus.NewLinkFrom(b.ExistingInterface)
if err != nil {
log.Println("Error creating Ethernet Alias: ", err.Error())
log.Println("Problematic interface: ", b.ExistingInterface)
}
if err := br.SetLinkIp(brIp, brIpNet); err != nil {
log.Println("Error setting UP the IP: ", err.Error())
} else {
log.Printf("%s configured with %s\n", b.ExistingInterface, brIp.String())
}
// refresh ARP , should not be necessary, but we know, Cisco FA
b.RefreshArp()
}
func (b *AbstractBridge) removeIPandBridgeInt() {
// we want the program to recover in case of issues
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <removeIPandBridgeInt()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
br, err := tenus.NewLinkFrom(b.ExistingInterface)
if err != nil {
log.Println("Error creating Ethernet Handle: ", err.Error())
log.Println("Problematic interface: ", b.ExistingInterface)
}
brIp, brIpNet, err := net.ParseCIDR(b.BridgeIpCIDR)
if err != nil {
log.Println("Error parsing CIDR: ", err.Error())
}
if err := br.UnsetLinkIp(brIp, brIpNet); err != nil {
log.Println("Error setting DOWN the IP: ", err.Error())
}
}
func (b *AbstractBridge) IsActive() bool {
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <Isactive()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
var bridgeip string
brIp, _, err := net.ParseCIDR(b.BridgeIpCIDR)
if err != nil {
log.Println("IsActive : problem parsing the IP/CIDR: ", err.Error())
} else {
bridgeip = brIp.String()
}
log.Println("Check for active IP: ", bridgeip)
pinger, err := ping.NewPinger(bridgeip)
if err != nil {
log.Println("Unable to ping address: ", bridgeip)
log.Println("Ping error: " + err.Error())
}
// just in case it doesn't stops alone
defer pinger.Stop()
pinger.Count = 5
pinger.Interval = time.Duration(10 * time.Millisecond)
pinger.Timeout = time.Duration(1 * time.Second)
pinger.Run() // blocks until finished
stats := pinger.Statistics()
log.Println("Ping results for: ", bridgeip)
log.Printf("%d packet sent, %d packet recv\n", pinger.Count, stats.PacketsRecv)
log.Println("IsACTIVE: ", stats.PacketsRecv == pinger.Count)
return stats.PacketsRecv == pinger.Count
}
func (b *AbstractBridge) IsAssigned() bool {
// we want the program to recover in case of issues
defer func() {
if r := recover(); r != nil {
fmt.Println("An error happened in <IsAssigned()>, but Zoreide recovered. ")
fmt.Println("Error was: ", r)
}
}()
var (
ief *net.Interface
addrs []net.Addr
err error
)
interfaceName := b.ExistingInterface
if ief, err = net.InterfaceByName(interfaceName); err != nil { // get interface
log.Printf("Interface %s does not exist or not manageable\n", interfaceName)
log.Printf("Error is: %s\n", err.Error())
return false
}
if addrs, err = ief.Addrs(); err != nil { // get addresses
log.Printf("Cannot read IPs of interface %s\n", interfaceName)
log.Printf("Error is: %s\n", err.Error())
return false
}
if len(addrs) < 1 {
log.Printf("Interface has NO ip addresses")
return false
}
for _, addr := range addrs {
log.Println("Address found is: ", addr.String())
if addr.String() == b.BridgeIpCIDR {
log.Printf("Ip %s is assigned to interface %s", b.BridgeIpCIDR, interfaceName)
return true
}
}
log.Printf("Ip %s is NOT assigned to interface %s", b.BridgeIpCIDR, interfaceName)
return false
}