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 }