github.com/Cloud-Foundations/Dominator@v0.3.4/cmd/hyper-control/watchDhcp.go (about)

     1  package main
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/Cloud-Foundations/Dominator/lib/errors"
     9  	"github.com/Cloud-Foundations/Dominator/lib/fsutil"
    10  	"github.com/Cloud-Foundations/Dominator/lib/log"
    11  	"github.com/Cloud-Foundations/Dominator/lib/srpc"
    12  	proto "github.com/Cloud-Foundations/Dominator/proto/hypervisor"
    13  	dhcp "github.com/krolaw/dhcp4"
    14  )
    15  
    16  func watchDhcpSubcommand(args []string, logger log.DebugLogger) error {
    17  	var interfaceName string
    18  	if len(args) > 0 {
    19  		interfaceName = args[0]
    20  	}
    21  	if err := watchDhcp(interfaceName, logger); err != nil {
    22  		return fmt.Errorf("error watching DHCP: %s", err)
    23  	}
    24  	return nil
    25  }
    26  
    27  func watchDhcp(interfaceName string, logger log.DebugLogger) error {
    28  	if *hypervisorHostname == "" {
    29  		return errors.New("unspecified Hypervisor")
    30  	}
    31  	clientName := fmt.Sprintf("%s:%d", *hypervisorHostname, *hypervisorPortNum)
    32  	client, err := srpc.DialHTTP("tcp", clientName, 0)
    33  	if err != nil {
    34  		return err
    35  	}
    36  	defer client.Close()
    37  	conn, err := client.Call("Hypervisor.WatchDhcp")
    38  	if err != nil {
    39  		return err
    40  	}
    41  	defer conn.Close()
    42  	request := proto.WatchDhcpRequest{Interface: interfaceName}
    43  	if err := conn.Encode(request); err != nil {
    44  		return err
    45  	}
    46  	if err := conn.Flush(); err != nil {
    47  		return err
    48  	}
    49  	dirname, err := os.MkdirTemp("",
    50  		"hyper-control.watch-dhcp."+*hypervisorHostname+".")
    51  	if err != nil {
    52  		return err
    53  	}
    54  	logger.Printf("Results in directory: %s\n", dirname)
    55  	for counter := 0; true; counter++ {
    56  		var reply proto.WatchDhcpResponse
    57  		if err := conn.Decode(&reply); err != nil {
    58  			return err
    59  		}
    60  		if err := errors.New(reply.Error); err != nil {
    61  			return err
    62  		}
    63  		filename := fmt.Sprintf("%s.%.5d", reply.Interface, counter)
    64  		file, err := os.Create(filepath.Join(dirname, filename))
    65  		if err != nil {
    66  			return err
    67  		}
    68  		file.Write(reply.Packet)
    69  		file.Close()
    70  		packet := dhcp.Packet(reply.Packet)
    71  		options := packet.ParseOptions()
    72  		msgType := dhcp.MessageType(options[dhcp.OptionDHCPMessageType][0])
    73  		logger.Printf("Counter: %d, message type: %s, from: %s, options:\n",
    74  			counter, msgType, packet.CHAddr())
    75  		optionsDirname := filepath.Join(dirname, filename) + ".options"
    76  		os.Mkdir(optionsDirname, fsutil.DirPerms)
    77  		for code, value := range options {
    78  			logger.Printf("  Code: %s, value: %0x\n", code, value)
    79  			optionFilename := fmt.Sprintf("%s/%d_%s",
    80  				optionsDirname, code, code)
    81  			file, err := os.Create(optionFilename)
    82  			if err != nil {
    83  				return err
    84  			}
    85  			file.Write(value)
    86  			file.Close()
    87  		}
    88  	}
    89  	return nil
    90  }