Skip to content

Instantly share code, notes, and snippets.

@puhitaku
Created November 23, 2017 00:35
Show Gist options
  • Save puhitaku/aad65d7d457da8ca6d8f464630e55823 to your computer and use it in GitHub Desktop.
Save puhitaku/aad65d7d457da8ca6d8f464630e55823 to your computer and use it in GitHub Desktop.
macOSのClonable Interface一覧を取るやつ in Golang
#include <stdio.h>
#include <sys/sockio.h>
#include <net/if.h>
int main() {
printf("%lx", SIOCIFGCLONERS);
return 0;
}
package main
import (
"syscall"
"unsafe"
"fmt"
"os"
"encoding/json"
"regexp"
"strings"
)
const(
SIOCIFGCLONERS = 0xc0106981
)
type if_clonereq struct {
ifcr_total uint32
ifcr_count uint32
ifcr_buffer []byte
}
func formatIfClonereq(req *if_clonereq) string {
re := regexp.MustCompile("\\s?([^\\x00]+)\\x00*")
human := re.ReplaceAllString(string(req.ifcr_buffer), "$1 ")
s := map[string]string{
"ifcr_total": fmt.Sprint(req.ifcr_total),
"ifcr_count": fmt.Sprint(req.ifcr_count),
"ifcr_buffer": strings.Trim(human, " "),
}
j, _ := json.MarshalIndent(s, "", " ")
return string(j)
}
func main() {
fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_DGRAM, 0)
if err != nil {
fmt.Fprint(os.Stderr, err.Error())
return
}
req := if_clonereq{
ifcr_buffer: []byte{},
}
// Retrieve number of clonable ifs
_, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCIFGCLONERS, uintptr(unsafe.Pointer(&req)))
if errno != 0 {
fmt.Printf("Errno: %s", errno.Error())
}
fmt.Printf("First:\n%s\n\n", formatIfClonereq(&req))
if req.ifcr_total > 0 {
req.ifcr_count = req.ifcr_total
req.ifcr_buffer = make([]byte, syscall.IFNAMSIZ * req.ifcr_total)
} else {
return
}
// Retrieve names
_, _, errno = syscall.Syscall(syscall.SYS_IOCTL, uintptr(fd), SIOCIFGCLONERS, uintptr(unsafe.Pointer(&req)))
if errno != 0 {
fmt.Printf("Errno: %s", errno.Error())
}
fmt.Printf("Second:\n%s\n", formatIfClonereq(&req))
fmt.Println(string(req.ifcr_buffer))
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment