Exemple #1
0
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
}
Exemple #2
0
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()
}
Exemple #3
0
// 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
}
Exemple #4
0
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)
}
Exemple #5
0
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
}
Exemple #6
0
// 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
}