1. 程式人生 > >go語言,取linux系統網絡卡MAC和硬碟序列號

go語言,取linux系統網絡卡MAC和硬碟序列號

利用cgo,實現在go語言中呼叫c語言函式,取MAC和硬碟序列號。cgo中需要注意的:*/和import "C"兩行之間不能有其它內容!

package main

/* #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <sys/ioctl.h> #include <net/if.h> #include <unistd.h>

#include <errno.h> #include <fcntl.h> #include <linux/hdreg.h>

char * mac_serial(char *iface){     int fd;      struct ifreq ifr;     unsigned char *mac = NULL;     char *rtn=malloc(21);

    errno=0;     memset(&ifr, 0, sizeof(ifr));

    fd = socket(AF_INET, SOCK_DGRAM, 0); 

    ifr.ifr_addr.sa_family = AF_INET;     strncpy(ifr.ifr_name , iface , IFNAMSIZ-1);

    if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) {         mac = (unsigned char *)ifr.ifr_hwaddr.sa_data;

        sprintf(rtn,"%.2X:%.2X:%.2X:%.2X:%.2X:%.2X" , mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);     }   

    close(fd);

    return rtn; }

char * disk_serial(char *devname) {     static struct hd_driveid hd;     int fd;      char *rtn=malloc(21);     errno=0;     

    if (geteuid() >  0) { //not root         errno=1;         return NULL;     }

    if ((fd = open(devname, O_RDONLY|O_NONBLOCK)) < 0) { //can't open         errno=2;         return NULL;     }

    if (!ioctl(fd, HDIO_GET_IDENTITY, &hd)) {         sprintf(rtn,"%.20s",hd.serial_no);         return rtn;     } else if (errno == -ENOMSG) {         errno=3;         return NULL;     } else { //HDIO_GET_IDENTITY         errno=4;         return NULL;     } }

*/ import "C" import "unsafe" import "fmt" import "os"

func main(){     fmt.Print("=====golang, network mac & disk serial =====\n")

    ethName :="eth0"    //enp03s     diskName :="/dev/sda"

    if len(os.Args)>=2 {         ethName=os.Args[1]         diskName=os.Args[2]     }

    mac,err0 := C.mac_serial(C.CString(ethName))     defer C.free(unsafe.Pointer(mac))     if err0 == nil{         fmt.Printf("mac_serial:%s\n",C.GoString(mac))     } else{         fmt.Printf("mac_serial error:%s\n",err0)     }

    str1,err := C.disk_serial(C.CString(diskName))     defer C.free(unsafe.Pointer(str1))     if err == nil{         fmt.Printf("disk_serial:%s\n",C.GoString(str1))     } else{         fmt.Printf("disk_serial error:%s\n",err)     } }