func (tap_conn *TapConn) Open(mtu uint) (err error) {
	/* Open the tap/tun device */
	tap_conn.fd, err = syscall.Open("/dev/net/tun", syscall.O_RDWR, syscall.S_IRUSR|syscall.S_IWUSR|syscall.S_IRGRP|syscall.S_IROTH)
	if err != nil {
		return fmt.Errorf("Error opening device /dev/net/tun!: %s", err)
	}

	/* Prepare a struct ifreq structure for TUNSETIFF with tap settings */
	/* IFF_TAP: tap device, IFF_NO_PI: no extra packet information */
	ifr_flags := uint16(syscall.IFF_TAP | syscall.IFF_NO_PI)
	/* FIXME: Assumes little endian */
	ifr_struct := make([]byte, 32)
	ifr_struct[16] = byte(ifr_flags)
	ifr_struct[17] = byte(ifr_flags >> 8)
	r0, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(tap_conn.fd), syscall.TUNSETIFF, uintptr(unsafe.Pointer(&ifr_struct[0])))
	if r0 != 0 {
		tap_conn.Close()
		return fmt.Errorf("Error setting tun/tap type!: %s", err)
	}

	/* Extract the assigned interface name into a string */
	tap_conn.ifname = string(ifr_struct[0:16])

	/* Create a raw socket for our tap interface, so we can set the MTU */
	tap_sockfd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, syscall.ETH_P_ALL)
	if err != nil {
		tap_conn.Close()
		return fmt.Errorf("Error creating packet socket!: %s", err)
	}
	/* We won't need the socket after we've set the MTU and brought the
	 * interface up */
	defer syscall.Close(tap_sockfd)

	/* Bind the raw socket to our tap interface */
	err = syscall.BindToDevice(tap_sockfd, tap_conn.ifname)
	if err != nil {
		tap_conn.Close()
		return fmt.Errorf("Error binding packet socket to tap interface!: %s", err)
	}

	/* Prepare a ifreq structure for SIOCSIFMTU with MTU setting */
	ifr_mtu := mtu
	/* FIXME: Assumes little endian */
	ifr_struct[16] = byte(ifr_mtu)
	ifr_struct[17] = byte(ifr_mtu >> 8)
	ifr_struct[18] = byte(ifr_mtu >> 16)
	ifr_struct[19] = byte(ifr_mtu >> 24)
	r0, _, err = syscall.Syscall(syscall.SYS_IOCTL, uintptr(tap_sockfd), syscall.SIOCSIFMTU, uintptr(unsafe.Pointer(&ifr_struct[0])))
	if r0 != 0 {
		tap_conn.Close()
		return fmt.Errorf("Error setting MTU on tap interface!: %s", err)
	}

	/* Get the current interface flags in ifr_struct */
	r0, _, err = syscall.Syscall(syscall.SYS_IOCTL, uintptr(tap_sockfd), syscall.SIOCGIFFLAGS, uintptr(unsafe.Pointer(&ifr_struct[0])))
	if r0 != 0 {
		tap_conn.Close()
		return fmt.Errorf("Error getting tap interface flags!: %s", err)
	}
	/* Update the interface flags to bring the interface up */
	/* FIXME: Assumes little endian */
	ifr_flags = uint16(ifr_struct[16]) | uint16(ifr_struct[17]<<8)
	ifr_flags |= syscall.IFF_UP | syscall.IFF_RUNNING
	ifr_struct[16] = byte(ifr_flags)
	ifr_struct[17] = byte(ifr_flags >> 8)
	r0, _, err = syscall.Syscall(syscall.SYS_IOCTL, uintptr(tap_sockfd), syscall.SIOCSIFFLAGS, uintptr(unsafe.Pointer(&ifr_struct[0])))
	if r0 != 0 {
		tap_conn.Close()
		return fmt.Errorf("Error bringing up tap interface!: %s", err)
	}

	return nil
}
Exemple #2
0
// BindToDevice binds a UDPConn to a network interface.
func (c *UDPConn) BindToDevice(device string) os.Error {
	if !c.ok() {
		return os.EINVAL
	}
	c.fd.incref()
	defer c.fd.decref()
	return os.NewSyscallError("setsockopt", syscall.BindToDevice(c.fd.sysfd, device))
}
Exemple #3
0
// sendARP sends the given ARP message via the specified interface.
func sendARP(iface *net.Interface, m *arpMessage) error {
	fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_DGRAM, int(htons(syscall.ETH_P_ARP)))
	if err != nil {
		return fmt.Errorf("failed to get raw socket: %v", err)
	}
	defer syscall.Close(fd)

	if err := syscall.BindToDevice(fd, iface.Name); err != nil {
		return fmt.Errorf("failed to bind to device: %v", err)
	}

	ll := syscall.SockaddrLinklayer{
		Protocol: htons(syscall.ETH_P_ARP),
		Ifindex:  iface.Index,
		Pkttype:  0, // syscall.PACKET_HOST
		Hatype:   m.hardwareType,
		Halen:    m.hardwareAddressLength,
	}
	target := ethernetBroadcast
	if m.opcode == opARPReply {
		target = m.targetHardwareAddress
	}
	for i := 0; i < len(target); i++ {
		ll.Addr[i] = target[i]
	}

	b, err := m.bytes()
	if err != nil {
		return fmt.Errorf("failed to convert ARP message: %v", err)
	}

	if err := syscall.Bind(fd, &ll); err != nil {
		return fmt.Errorf("failed to bind: %v", err)
	}
	if err := syscall.Sendto(fd, b, 0, &ll); err != nil {
		return fmt.Errorf("failed to send: %v", err)
	}

	return nil
}
Exemple #4
0
func main() {
	fmt.Println(net.InterfaceAddrs())
	l, _ := net.Interfaces()
	for _, v := range l {
		fmt.Println(v)
	}
	fd, err := syscall.Socket(syscall.AF_INET, syscall.SOCK_PACKET, 0x0300)
	if err != nil {
		fmt.Println("socket", err)
	}
	defer syscall.Close(fd)

	if err = syscall.BindToDevice(fd, "eth1"); err != nil {
		fmt.Println("bind", err)
		panic(err)
	}

	for {
		b := make([]byte, 100)
		_, _, _ = syscall.Recvfrom(fd, b, 0)
		if !IsIcmpPac(b) {
			continue
		}
		//fmt.Printf("%5x\n", b[12:14])
		//continue
		for k, v := range b {
			if k%4 == 2 {
				fmt.Println()
			}
			fmt.Printf("|%4d: %5d:0x%-5x|", k, v, v)
		}
		fmt.Println("\na packet-----------")
	}
	time.Sleep(1 * time.Second)
	fmt.Println(fd)

}
Exemple #5
0
// BindToDevice binds the socket associated with fd to device.
func BindToDevice(fd int, device string) error {
	return syscall.BindToDevice(fd, device)
}