github.com/zooyer/miskit@v1.0.71/device/device.go (about) 1 /** 2 * @Author: zzy 3 * @Email: zhangzhongyuan@didiglobal.com 4 * @Description: 5 * @File: device.go 6 * @Package: device 7 * @Version: 1.0.0 8 * @Date: 2022/10/4 14:05 9 */ 10 11 package device 12 13 import ( 14 "fmt" 15 "net" 16 "os/exec" 17 "runtime" 18 "sort" 19 "strings" 20 21 "github.com/yumaojun03/dmidecode" 22 "github.com/zooyer/embed/log" 23 ) 24 25 func containsAny(value string, any ...string) bool { 26 for _, v := range any { 27 if strings.Contains(value, v) { 28 return true 29 } 30 } 31 32 return false 33 } 34 35 func execCommand(name string, arg ...string) (output string, err error) { 36 out, err := exec.Command(name, arg...).CombinedOutput() 37 if err != nil { 38 return 39 } 40 41 return string(out), nil 42 } 43 44 func wmicByKey(t, key string) string { 45 output, err := execCommand("wmic", t, "get", key) 46 if err != nil { 47 log.ZError("wmicByKey execCommand error:", err.Error()) 48 return "" 49 } 50 51 // 去掉前缀 52 output = strings.TrimSpace(output) 53 output = strings.TrimPrefix(output, key) 54 output = strings.TrimSpace(output) 55 56 // 多个结果以\n分隔 57 lines := strings.Split(output, "\n") 58 outs := make([]string, 0, len(lines)) 59 for _, line := range lines { 60 if line = strings.TrimSpace(line); line == "" { 61 continue 62 } 63 outs = append(outs, line) 64 } 65 output = strings.Join(outs, "\n") 66 67 // 去掉无效值 68 output = strings.TrimPrefix(output, "None") 69 output = strings.TrimPrefix(output, "Default string") 70 71 return output 72 } 73 74 func dmiDecode(t string) map[string]string { 75 output, err := execCommand("dmidecode", "-q", "-t", t) 76 if err != nil { 77 log.ZError("dmiDecode execCommand error:", err.Error()) 78 return nil 79 } 80 81 var info = make(map[string]string) 82 lines := strings.Split(output, "\n") 83 if len(lines) > 0 { 84 lines = lines[1:] 85 } 86 87 for _, line := range lines { 88 if line = strings.TrimSpace(line); line == "" { 89 continue 90 } 91 92 fields := strings.Split(line, ":") 93 if len(fields) != 2 { 94 continue 95 } 96 97 name := strings.TrimSpace(fields[0]) 98 value := strings.TrimSpace(fields[1]) 99 if name == "" { 100 continue 101 } 102 103 info[name] = value 104 } 105 106 return info 107 } 108 109 func dmiDecodeByKey(t, key string) string { 110 return dmiDecode(t)[key] 111 } 112 113 func getMacAddress() (addr []string, err error) { 114 interfaces, err := net.Interfaces() 115 if err != nil { 116 return 117 } 118 119 defer sort.Strings(addr) 120 121 for _, i := range interfaces { 122 is, err := isPhysicalEthernet(i.Index) 123 if err != nil { 124 return nil, err 125 } 126 127 if !is || i.Flags&net.FlagLoopback != 0 { 128 continue 129 } 130 131 addr = append(addr, fmt.Sprintf("%s", i.HardwareAddr.String())) 132 133 //switch runtime.GOOS { 134 //case "windows": 135 //case "darwin": 136 // fallthrough 137 //case "linux": 138 // if !containsAny(i.Name, "en", "eno", "ens", "enp2s", "eth") { 139 // continue 140 // } 141 // 142 // if containsAny(i.Name, "bridge", "vmenet", "utun") { 143 // continue 144 // } 145 //} 146 } 147 148 return 149 } 150 151 func getBaseboardIDByWindows() string { 152 return wmicByKey("baseboard", "SerialNumber") 153 } 154 155 func getBaseboardIDByDarwin() []string { 156 return nil 157 panic("implement") 158 } 159 160 func getBaseboardIDByLinux() string { 161 return dmiDecodeByKey("2", "Serial Number") 162 } 163 164 func getBiosSNByWindows() string { 165 return strings.ReplaceAll(wmicByKey("bios", "SerialNumber"), " ", "") 166 } 167 168 func getBiosSNByDarwin() []string { 169 output, err := execCommand("system_profiler", "SPHardwareDataType") 170 if err != nil { 171 log.ZError("getBiosSNByDarwin execCommand error:", err.Error()) 172 return nil 173 } 174 175 var sn []string 176 for _, line := range strings.Split(output, "\n") { 177 if strings.Contains(line, "Serial Number (system)") && strings.Contains(line, ":") { 178 sn = append(sn, strings.TrimSpace(strings.Split(line, ":")[1])) 179 } 180 } 181 182 return sn 183 } 184 185 func getBiosSNByLinux() string { 186 return strings.ReplaceAll(dmiDecodeByKey("1", "Serial Number"), "System Serial Number", "") 187 } 188 189 func getCPUIDByWindows() []string { 190 return strings.Split(wmicByKey("cpu", "ProcessorId"), "\n") 191 } 192 193 func getCPUIDByDarwin() []string { 194 return nil 195 panic("implement") 196 } 197 198 func getCPUIDByLinux() []string { 199 return strings.Split(dmiDecodeByKey("4", "ID"), " ") 200 } 201 202 func getOSUUIDByWindows() string { 203 return wmicByKey("csproduct", "UUID") 204 } 205 206 func getOSUUIDByDarwin() []string { 207 return nil 208 panic("implement") 209 } 210 211 func getOSUUIDByLinux() string { 212 output, err := execCommand("dmidecode", "-s", "system-uuid") 213 if err != nil { 214 log.ZError("getOSUUIDByLinux execCommand error:", err.Error()) 215 return "" 216 } 217 218 output = strings.TrimSpace(output) 219 220 return output 221 } 222 223 func BaseboardSN() []string { 224 switch runtime.GOOS { 225 case "darwin": 226 return getBaseboardIDByDarwin() 227 case "linux": 228 return []string{getBaseboardIDByLinux()} 229 case "windows": 230 return []string{getBaseboardIDByWindows()} 231 dmi, err := dmidecode.New() 232 if err != nil { 233 return nil 234 } 235 236 boards, err := dmi.BaseBoard() 237 if err != nil { 238 return nil 239 } 240 241 var sn = make([]string, 0, len(boards)) 242 for _, board := range boards { 243 sn = append(sn, fmt.Sprintf("%s %s", board.Manufacturer, board.SerialNumber)) 244 } 245 246 return sn 247 } 248 249 return nil 250 } 251 252 func BiosSN() []string { 253 switch runtime.GOOS { 254 case "darwin": 255 return getBiosSNByDarwin() 256 case "linux": 257 return []string{getBiosSNByLinux()} 258 case "windows": 259 return []string{getBiosSNByWindows()} 260 dmi, err := dmidecode.New() 261 if err != nil { 262 return nil 263 } 264 265 bios, err := dmi.BIOS() 266 if err != nil { 267 return nil 268 } 269 270 var sn = make([]string, len(bios)) 271 for _, b := range bios { 272 sn = append(sn, fmt.Sprintf("%s %s %v", strings.TrimSpace(b.Vendor), strings.TrimSpace(b.BIOSVersion), b.Characteristics)) 273 } 274 275 return sn 276 } 277 278 return nil 279 } 280 281 func ProcessorSN() []string { 282 switch runtime.GOOS { 283 case "darwin": 284 return getCPUIDByDarwin() 285 case "linux": 286 return getCPUIDByLinux() 287 case "windows": 288 return getCPUIDByWindows() 289 dmi, err := dmidecode.New() 290 if err != nil { 291 return nil 292 } 293 294 processor, err := dmi.Processor() 295 if err != nil { 296 return nil 297 } 298 299 var id = make([]string, 0, len(processor)) 300 for _, p := range processor { 301 id = append(id, fmt.Sprintf("%s %s", strings.TrimSpace(p.Version), p.ID)) 302 } 303 304 return id 305 } 306 307 return nil 308 } 309 310 func MAC() []string { 311 addr, _ := getMacAddress() 312 return addr 313 } 314 315 func SystemID() []string { 316 switch runtime.GOOS { 317 case "darwin": 318 return getOSUUIDByDarwin() 319 case "linux": 320 return []string{getOSUUIDByLinux()} 321 case "windows": 322 return []string{getOSUUIDByWindows()} 323 dmi, err := dmidecode.New() 324 if err != nil { 325 return nil 326 } 327 328 system, err := dmi.System() 329 if err != nil { 330 return nil 331 } 332 333 var id = make([]string, 0, len(system)) 334 for _, s := range system { 335 id = append(id, fmt.Sprintf("%s %s %s", s.Manufacturer, s.ProductName, s.SerialNumber)) 336 } 337 338 return id 339 } 340 341 return nil 342 }