func makeSparseFile() error { os.Remove(testFileName) f, err := os.Create(testFileName) if err != nil { return err } defer f.Close() const ( FSCTL_SET_SPARSE = 0x000900c4 FSCTL_SET_ZERO_DATA = 0x000980c8 ) err = syscall.DeviceIoControl(syscall.Handle(f.Fd()), FSCTL_SET_SPARSE, nil, 0, nil, 0, nil, nil) if err != nil { return err } _, err = f.Write([]byte("testing 1 2 3\n")) if err != nil { return err } _, err = f.Seek(1000000, 0) if err != nil { return err } _, err = f.Write([]byte("more data later\n")) if err != nil { return err } return nil }
func ExtractMacFromInterface(dev *Interface) string { mac := make([]byte, 6) var length uint32 err := syscall.DeviceIoControl(dev.file, TAP_IOCTL_GET_MAC, &mac[0], uint32(len(mac)), &mac[0], uint32(len(mac)), &length, nil) if err != nil { Log(Error, "Failed to get MAC from device") } var macAddr bytes.Buffer i := 0 for _, a := range mac { if a == 0 { macAddr.WriteString("00") } else if a < 16 { macAddr.WriteString(fmt.Sprintf("0%x", a)) } else { macAddr.WriteString(fmt.Sprintf("%x", a)) } if i < 5 { macAddr.WriteString(":") } i++ } Log(Info, "MAC: %s", macAddr.String()) return macAddr.String() }
// ConfigureInterface configures TAP interface by assigning it's IP and netmask using netsh Command func ConfigureInterface(dev *Interface, ip, mac, device, tool string) error { dev.IP = ip dev.Mask = "255.255.255.0" Log(Info, "Configuring %s. IP: %s Mask: %s", dev.Interface, dev.IP, dev.Mask) setip := exec.Command("netsh") setip.SysProcAttr = &syscall.SysProcAttr{} cmd := fmt.Sprintf(`netsh interface ip set address "%s" static %s %s`, dev.Interface, dev.IP, dev.Mask) Log(Info, "Executing: %s", cmd) setip.SysProcAttr.CmdLine = cmd err := setip.Run() if err != nil { Log(Error, "Failed to properly configure TAP device with netsh: %v", err) return err } in := []byte("\x01\x00\x00\x00") var length uint32 err = syscall.DeviceIoControl(dev.file, TAP_IOCTL_SET_MEDIA_STATUS, &in[0], uint32(len(in)), &in[0], uint32(len(in)), &length, nil) if err != nil { Log(Error, "Failed to change device status to 'connected': %v", err) return err } return nil }
func createDirLink(link string, rdb *_REPARSE_DATA_BUFFER) error { err := os.Mkdir(link, 0777) if err != nil { return err } linkp := syscall.StringToUTF16(link) fd, err := syscall.CreateFile(&linkp[0], syscall.GENERIC_WRITE, 0, nil, syscall.OPEN_EXISTING, syscall.FILE_FLAG_OPEN_REPARSE_POINT|syscall.FILE_FLAG_BACKUP_SEMANTICS, 0) if err != nil { return err } defer syscall.CloseHandle(fd) buflen := uint32(rdb.header.ReparseDataLength) + uint32(unsafe.Sizeof(rdb.header)) var bytesReturned uint32 return syscall.DeviceIoControl(fd, windows.FSCTL_SET_REPARSE_POINT, (*byte)(unsafe.Pointer(&rdb.header)), buflen, nil, 0, &bytesReturned, nil) }
func IoctlDiskPerformance(h syscall.Handle) (*DiskPerformance, error) { var ( diskPerf DiskPerformance bytesReturned uint32 ) err := syscall.DeviceIoControl(h, IOCTL_DISK_PERFORMANCE, nil, 0, (*byte)(unsafe.Pointer(&diskPerf)), uint32(unsafe.Sizeof(diskPerf)), &bytesReturned, nil) if err != nil { return nil, err } return &diskPerf, nil }
// NewTAP find and open a TAP device. func newTAP() (ifce *Interface, err error) { deviceid, err := getdeviceid() if err != nil { return nil, err } path := "\\\\.\\Global\\" + deviceid + ".tap" pathp, err := syscall.UTF16PtrFromString(path) if err != nil { return nil, err } // type Handle uintptr file, err := syscall.CreateFile(pathp, syscall.GENERIC_READ|syscall.GENERIC_WRITE, uint32(syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE), nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_SYSTEM, 0) // if err hanppens, close the interface. defer func() { if err != nil { syscall.Close(file) } if err := recover(); err != nil { syscall.Close(file) } }() if err != nil { return nil, err } var bytesReturned uint32 // find the mac address of tap device. mac := make([]byte, 6) err = syscall.DeviceIoControl(file, tap_win_ioctl_get_mac, &mac[0], uint32(len(mac)), &mac[0], uint32(len(mac)), &bytesReturned, nil) if err != nil { return nil, err } //TUN //code2 := []byte{0x0a, 0x03, 0x00, 0x01, 0x0a, 0x03, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00} //err = syscall.DeviceIoControl(file, tap_ioctl_config_tun, &code2[0], uint32(12), &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) //if err != nil { // log.Fatalln("code2 err:", err) //} fd := os.NewFile(uintptr(file), path) ifce = &Interface{tap: true, file: fd} copy(ifce.mac[:6], mac[:6]) // find the name of tap interface(to set the ip) hwaddr_equal := func(a net.HardwareAddr, b []byte) bool { for i := 0; i < 6; i++ { if a[i] != b[i] { return false } } return true } ifces, err := net.Interfaces() if err != nil { return } // bring up device. rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE) code := []byte{0x01, 0x00, 0x00, 0x00} err = syscall.DeviceIoControl(file, tap_ioctl_set_media_status, &code[0], uint32(4), &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil) if err != nil { return nil, err } for _, v := range ifces { if hwaddr_equal(v.HardwareAddr[:6], mac[:6]) { ifce.name = v.Name //ifce.ignoreDefaultRoutes() return } } err = IfceNameNotFound return }
func OpenTunTap(addr net.IP, network net.IP, mask net.IP) (Tun, error) { t := new(tun) id, err := getTuntapComponentId() if err != nil { return nil, err } t.device_path = fmt.Sprintf(`\\.\Global\%s.tap`, id) name := syscall.StringToUTF16(t.device_path) tuntap, err := syscall.CreateFile( &name[0], syscall.GENERIC_READ|syscall.GENERIC_WRITE, syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE, nil, syscall.OPEN_EXISTING, syscall.FILE_ATTRIBUTE_SYSTEM|syscall.FILE_FLAG_OVERLAPPED, 0) if err != nil { fmt.Println("here") return nil, err } var returnLen uint32 var configTunParam []byte = append(addr, network...) configTunParam = append(configTunParam, mask...) fmt.Println(configTunParam) configTunParam = []byte{10, 0, 0, 1, 10, 0, 0, 0, 255, 255, 255, 0} if err = syscall.DeviceIoControl( tuntap, TAP_IOCTL_CONFIG_TUN, &configTunParam[0], uint32(len(configTunParam)), &configTunParam[0], uint32(len(configTunParam)), &returnLen, nil); err != nil { fmt.Println("here2") return nil, err } // get MTU // var umtu = make([]byte, 4) // if err = syscall.DeviceIoControl( // tuntap, // TAP_IOCTL_GET_MTU, // nil, // 0, // &umtu[0], // uint32(len(umtu)), // &returnLen, // nil); err != nil { // fmt.Println("here3") // return nil, err // } // mtu := binary.LittleEndian.Uint32(umtu) mtu := 1500 // set connect. inBuffer := []byte("\x01\x00\x00\x00") if err = syscall.DeviceIoControl( tuntap, TAP_IOCTL_SET_MEDIA_STATUS, &inBuffer[0], uint32(len(inBuffer)), &inBuffer[0], uint32(len(inBuffer)), &returnLen, nil); err != nil { return nil, err } t.fd = tuntap t.mtu = int(mtu) return t, nil }