ssh-client-orchestrate/main.go

140 lines
2.9 KiB
Go
Raw Normal View History

package main
import (
"bufio"
"fmt"
"log"
"os"
// "time"
"strconv"
"math/rand"
"github.com/songgao/packets/ethernet"
"github.com/songgao/water"
"github.com/vishvananda/netlink"
)
type Client struct {
ifce *water.Interface
hostname string
addr *netlink.Addr
}
// -- funcs --
// writes out desired hostname to file. generates a small bash script for
// the client to run
//func generateNewClient() {
//
// var desired_hostname string
// fmt.Printf("Please enter a desired hostname for the new client: ")
//
// scanner := bufio.NewScanner(os.Stdin)
// scanner.Scan()
// err := scanner.Err()
// if err != nil {
// log.Fatal(err)
// panic(err)
// }
// desired_hostname = scanner.Text()
//
//
//}
// maps ip --> hostname
// used to verify collisions
var client_leases = make(map[string]string)
func generateClientTUN(hn string) Client {
// configure TUN interface
config := water.Config{
DeviceType: water.TUN,
}
config.Name = "tun_"+hn
cl_ifce, err := water.New(config)
if err != nil {
log.Fatal(err)
}
// Generate a free address to assign
var cl_Addr_str string
// This is a bad way of doing it, and only accounts for local conflicts
// theres definitely a way to find if it conflicts somewhere else
// ideally, it shouldnt be locked to this 16 block, either. eventually,
// the allowed range (CIDR included) should be defined.
// this is an alpha for now, just to get *something* nice working
r := rand.New(rand.NewSource(255))
for {
var b1 int = int(r.Int31n(255))
var b2 int = int(r.Int31n(255))
cl_Addr_str = "." + strconv.Itoa(b1) + "." + strconv.Itoa(b2)
fmt.Println(cl_Addr_str)
_, isLeased := client_leases[cl_Addr_str]
if !isLeased {
break
}
}
cl_Link, err := netlink.LinkByName(config.Name)
if err != nil {
log.Fatal(err)
}
cl_Addr, err := netlink.ParseAddr("169.254"+cl_Addr_str+"/16")
if err != nil {
log.Fatal(err)
}
// register addr -> ifce with host
netlink.AddrAdd(cl_Link, cl_Addr)
return Client {
ifce: cl_ifce,
hostname: hn,
addr: cl_Addr,
}
}
func main() {
var desired_hostname string
fmt.Printf("your nosthanem is ")
hn, _ := os.Hostname()
fmt.Println(hn)
fmt.Printf("Please enter a desired hostname for the new client: ")
scanner := bufio.NewScanner(os.Stdin)
scanner.Scan()
err := scanner.Err()
if err != nil {
log.Fatal(err)
}
desired_hostname = scanner.Text()
var registered_client Client = generateClientTUN(desired_hostname)
log.Printf("interface name: %s\n", registered_client.ifce.Name())
var frame ethernet.Frame
ifce := registered_client.ifce
for {
frame.Resize(1500)
n, err := ifce.Read([]byte(frame))
if err != nil {
log.Fatal(err)
}
frame = frame[:n]
log.Printf("Dst: %s\n", frame.Destination())
log.Printf("Src: %s\n", frame.Source())
log.Printf("Ethertype: % x\n", frame.Ethertype())
log.Printf("Payload: % x\n", frame.Payload())
}
// generateNewClient()
}