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 }
// 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)) }
// 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 }
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) }
// BindToDevice binds the socket associated with fd to device. func BindToDevice(fd int, device string) error { return syscall.BindToDevice(fd, device) }