github.com/zaolin/u-root@v0.0.0-20200428085104-64aaafd46c6d/cmds/exp/ipmidump/ipmidump.go (about) 1 // Copyright 2019-2020 the u-root Authors. All rights reserved 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 // Synopsis: 6 // ipmidump [-option] 7 // 8 // Description: 9 // 10 // Options: 11 // -chassis : Print chassis power status. 12 // -sel : Print SEL information. 13 // -lan : Print IP information. 14 // -raw : Send raw command and print response. 15 // -help : Print help message. 16 package main 17 18 import ( 19 "flag" 20 "fmt" 21 "log" 22 "os" 23 "strconv" 24 "time" 25 26 "github.com/u-root/u-root/pkg/ipmi" 27 ) 28 29 const cmd = "ipmidump [options] " 30 31 var ( 32 flagChassis = flag.Bool("chassis", false, "print chassis power status") 33 flagSEL = flag.Bool("sel", false, "print SEL information") 34 flagLan = flag.Bool("lan", false, "Print IP address") 35 flagRaw = flag.Bool("raw", false, "Send IPMI raw command") 36 flagHelp = flag.Bool("help", false, "print help message") 37 ) 38 39 func itob(i int) bool { return i != 0 } 40 41 func init() { 42 defUsage := flag.Usage 43 flag.Usage = func() { 44 os.Args[0] = cmd 45 defUsage() 46 } 47 } 48 49 func main() { 50 flag.Parse() 51 52 if *flagHelp { 53 flag.Usage() 54 os.Exit(1) 55 } 56 57 if *flagChassis { 58 chassisInfo() 59 } 60 61 if *flagSEL { 62 selInfo() 63 } 64 65 if *flagLan { 66 lanConfig() 67 } 68 69 if *flagRaw { 70 sendRawCmd(flag.Args()) 71 } 72 } 73 74 func chassisInfo() { 75 allow := map[bool]string{true: "allowed", false: "not allowed"} 76 act := map[bool]string{true: "active", false: "inactive"} 77 state := map[bool]string{true: "true", false: "false"} 78 79 policy := map[int]string{ 80 0x0: "always-off", 81 0x1: "previous", 82 0x2: "always-on", 83 0x3: "unknown", 84 } 85 86 event := map[int]string{ 87 0x10: "IPMI command", 88 0x08: "power fault", 89 0x04: "power interlock", 90 0x02: "power overload", 91 0x01: "AC failed", 92 0x00: "none", 93 } 94 95 ipmi, err := ipmi.Open(0) 96 if err != nil { 97 fmt.Printf("Failed to open ipmi device: %v\n", err) 98 } 99 defer ipmi.Close() 100 101 if status, err := ipmi.GetChassisStatus(); err != nil { 102 fmt.Printf("Failed to get chassis power status: %v\n", err) 103 } else { 104 // Current power status 105 data := int(status.CurrentPowerState) 106 fmt.Println("Chassis power status") 107 fmt.Println("Power Restore Policy:", policy[(data>>5)&0x03]) 108 fmt.Println("Power Control Fault :", state[itob(data&0x10)]) 109 fmt.Println("Power Fault :", state[itob(data&0x08)]) 110 fmt.Println("Power Interlock :", act[itob(data&0x04)]) 111 fmt.Println("Power Overload :", state[itob(data&0x02)]) 112 fmt.Printf("Power Status : ") 113 if (data & 0x01) != 0 { 114 fmt.Println("on") 115 } else { 116 fmt.Println("off") 117 } 118 119 // Last power event 120 data = int(status.LastPowerEvent) 121 fmt.Println("Last Power Event :", event[data&0x1F]) 122 123 // Misc. chassis state 124 data = int(status.MiscChassisState) 125 fmt.Println("Misc. chassis state") 126 fmt.Println("Cooling/Fan Fault :", state[itob(data&0x08)]) 127 fmt.Println("Drive Fault :", state[itob(data&0x04)]) 128 fmt.Println("Front Panel Lockout :", act[itob(data&0x02)]) 129 fmt.Println("Chass Intrusion :", act[itob(data&0x01)]) 130 131 // Front panel button (optional) 132 data = int(status.FrontPanelButton) 133 if status.FrontPanelButton != 0 { 134 fmt.Println("Front Panel Button") 135 fmt.Println("Standby Button Disable :", allow[itob(data&0x80)]) 136 fmt.Println("Diagnostic Buttton Disable:", allow[itob(data&0x40)]) 137 fmt.Println("Reset Button Disable :", allow[itob(data&0x20)]) 138 fmt.Println("Power-off Button Disable :", allow[itob(data&0x10)]) 139 140 fmt.Println("Standby Button :", state[itob(data&0x08)]) 141 fmt.Println("Diagnostic Buttton :", state[itob(data&0x04)]) 142 fmt.Println("Reset Button :", state[itob(data&0x02)]) 143 fmt.Println("Power-off Button :", state[itob(data&0x01)]) 144 } else { 145 fmt.Println("Front Panel Button : none") 146 } 147 } 148 } 149 150 func selInfo() { 151 support := map[bool]string{true: "supported", false: "unsupported"} 152 153 ipmi, err := ipmi.Open(0) 154 if err != nil { 155 fmt.Printf("Failed to open ipmi device: %v\n", err) 156 } 157 defer ipmi.Close() 158 159 if info, err := ipmi.GetSELInfo(); err != nil { 160 fmt.Printf("Failed to get SEL information: %v\n", err) 161 } else { 162 fmt.Println("SEL information") 163 164 switch info.Version { 165 case 0x51: 166 fallthrough 167 case 0x02: 168 fmt.Printf("Version : %d.%d (1.5, 2.0 compliant)\n", info.Version&0x0F, info.Version>>4) 169 default: 170 fmt.Println("Version : unknown") 171 } 172 173 fmt.Println("Entries :", info.Entries) 174 fmt.Printf("Free Space : %d bytes\n", info.FreeSpace) 175 176 // Most recent addition/erase timestamp 177 fmt.Printf("Last Add Time : ") 178 if info.LastAddTime != 0xFFFFFFFF { 179 fmt.Println(time.Unix(int64(info.LastAddTime), 0)) 180 } else { 181 fmt.Println("not available") 182 } 183 184 fmt.Printf("Last Del Time : ") 185 if info.LastDelTime != 0xFFFFFFFF { 186 fmt.Println(time.Unix(int64(info.LastDelTime), 0)) 187 } else { 188 fmt.Println("not available") 189 } 190 191 // Operation Support 192 fmt.Printf("Overflow : ") 193 if (info.OpSupport & 0x80) != 0 { 194 fmt.Println("true") 195 } else { 196 fmt.Println("false") 197 } 198 199 data := int(info.OpSupport) 200 if (data & 0x0F) != 0 { 201 fmt.Println("Supported cmds") 202 fmt.Println("Delete :", support[itob(data&0x08)]) 203 fmt.Println("Partial Add :", support[itob(data&0x04)]) 204 fmt.Println("Reserve :", support[itob(data&0x02)]) 205 fmt.Println("Get Alloc Info :", support[itob(data&0x01)]) 206 } else { 207 fmt.Println("Supported cmds : none") 208 } 209 } 210 } 211 212 func lanConfig() { 213 const ( 214 setInProgress byte = iota 215 _ 216 _ 217 IPAddress 218 IPAddressSrc 219 MACAddress 220 ) 221 222 setInProgressStr := []string{ 223 "Set Complete", "Set In Progress", "Commit Write", "Reserved", 224 } 225 226 IPAddressSrcStr := []string{ 227 "Unspecified", "Static Address", "DHCP Address", "BIOS Assigned Address", 228 } 229 230 ipmi, err := ipmi.Open(0) 231 if err != nil { 232 log.Fatal(err) 233 } 234 defer ipmi.Close() 235 236 // data 1 completion code 237 // data 2 parameter revision, 0x11 238 // data 3:N data 239 240 // set in progress 241 if buf, err := ipmi.GetLanConfig(1, setInProgress); err != nil { 242 fmt.Printf("Failed to get LAN config: %v\n", err) 243 } else { 244 fmt.Printf("Set In Progress : ") 245 if int(buf[2]) < len(setInProgressStr) { 246 fmt.Println(setInProgressStr[buf[2]]) 247 } else { 248 fmt.Println("Unknown") 249 fmt.Printf("%v\n", buf) 250 } 251 } 252 253 // ip address source 254 if buf, err := ipmi.GetLanConfig(1, IPAddressSrc); err != nil { 255 fmt.Printf("Failed to get LAN config: %v\n", err) 256 } else { 257 fmt.Printf("IP Address Source : ") 258 if int(buf[2]) < len(IPAddressSrcStr) { 259 fmt.Println(IPAddressSrcStr[buf[2]]) 260 } else { 261 fmt.Println("Other") 262 fmt.Printf("%v\n", buf) 263 } 264 } 265 266 // ip address 267 if buf, err := ipmi.GetLanConfig(1, IPAddress); err != nil { 268 fmt.Printf("Failed to get LAN config: %v\n", err) 269 } else { 270 fmt.Printf("IP Address : ") 271 if len(buf) == 6 { 272 fmt.Printf("%d.%d.%d.%d\n", buf[2], buf[3], buf[4], buf[5]) 273 } else { 274 fmt.Printf("Unknown\n") 275 } 276 } 277 278 // MAC address 279 if buf, err := ipmi.GetLanConfig(1, MACAddress); err != nil { 280 fmt.Printf("Failed to get LAN config: %v\n", err) 281 } else { 282 fmt.Printf("MAC Address : ") 283 if len(buf) == 8 { 284 fmt.Printf("%02x:%02x:%02x:%02x:%02x:%02x\n", buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]) 285 } else { 286 fmt.Printf("Unknown\n") 287 } 288 } 289 } 290 291 func sendRawCmd(cmds []string) { 292 ipmi, err := ipmi.Open(0) 293 if err != nil { 294 log.Fatal(err) 295 } 296 defer ipmi.Close() 297 298 data := make([]byte, 0) 299 300 for _, cmd := range cmds { 301 val, err := strconv.ParseInt(cmd, 0, 16) 302 if err != nil { 303 fmt.Printf("Invalid syntax: \"%s\"\n", cmd) 304 return 305 } 306 data = append(data, byte(val)) 307 } 308 309 if buf, err := ipmi.RawCmd(data); err != nil { 310 fmt.Printf("Unable to send RAW command: %v\n", err) 311 } else { 312 for i, x := range buf { 313 fmt.Printf("| 0x%-2x ", x) 314 if i%8 == 7 || i == len(buf)-1 { 315 fmt.Printf("|\n") 316 } 317 } 318 } 319 }