예제 #1
0
func readLoop(c *ipv4.PacketConn) {

	log.Printf("readLoop: reading")

	buf := make([]byte, 10000)

	for {
		n, cm, _, err1 := c.ReadFrom(buf)
		if err1 != nil {
			log.Printf("readLoop: ReadFrom: error %v", err1)
			break
		}

		var name string

		ifi, err2 := net.InterfaceByIndex(cm.IfIndex)
		if err2 != nil {
			log.Printf("readLoop: unable to solve ifIndex=%d: error: %v", cm.IfIndex, err2)
		}

		if ifi == nil {
			name = "ifname?"
		} else {
			name = ifi.Name
		}

		log.Printf("readLoop: recv %d bytes from %s to %s on %s", n, cm.Src, cm.Dst, name)
	}

	log.Printf("readLoop: exiting")
}
예제 #2
0
파일: coreos.go 프로젝트: jonboulle/fleet
func getDefaultGatewayIface() *net.Interface {
	log.Debug("Attempting to retrieve IP route info from netlink")

	routes, err := netlink.RouteList(nil, 0)
	if err != nil {
		log.Debugf("Unable to detect default interface: %v", err)
		return nil
	}

	if len(routes) == 0 {
		log.Debugf("Netlink returned zero routes")
		return nil
	}

	for _, route := range routes {
		// a nil Dst means that this is the default route.
		if route.Dst == nil {
			i, err := net.InterfaceByIndex(route.LinkIndex)
			if err != nil {
				log.Debugf("Found default route but could not determine interface")
				continue
			}
			log.Debugf("Found default route with interface %v", i)
			return i
		}
	}

	log.Debugf("Unable to find default route")
	return nil
}
예제 #3
0
func udpReader(c *ipv4.PacketConn, ifname, hostPort string) {

	log.Printf("udpReader: reading multicast")

	defer c.Close()

	buf := make([]byte, 10000)

	for {
		n, cm, _, err1 := c.ReadFrom(buf)
		if err1 != nil {
			log.Printf("udpReader: ReadFrom: error %v", err1)
			break
		}

		ifi, err2 := net.InterfaceByIndex(cm.IfIndex)
		if err2 != nil {
			log.Printf("udpReader: could not solve ifindex=%d: %v", cm.IfIndex, err2)
		}

		ifname := "ifname?"
		if ifi != nil {
			ifname = ifi.Name
		}

		log.Printf("udpReader: recv %d bytes from %s to %s on %s (ifindex=%d)", n, cm.Src, cm.Dst, ifname, cm.IfIndex)
	}

	log.Printf("udpReader: exiting")
}
예제 #4
0
func findPairInterfaceOfContainerInterface(e exec.Interface, containerInterfaceName, containerDesc string, nsenterArgs []string) (string, error) {
	nsenterPath, err := e.LookPath("nsenter")
	if err != nil {
		return "", err
	}
	ethtoolPath, err := e.LookPath("ethtool")
	if err != nil {
		return "", err
	}

	nsenterArgs = append(nsenterArgs, "-F", "--", ethtoolPath, "--statistics", containerInterfaceName)
	output, err := e.Command(nsenterPath, nsenterArgs...).CombinedOutput()
	if err != nil {
		return "", fmt.Errorf("Unable to query interface %s of container %s: %v: %s", containerInterfaceName, containerDesc, err, string(output))
	}
	// look for peer_ifindex
	match := ethtoolOutputRegex.FindSubmatch(output)
	if match == nil {
		return "", fmt.Errorf("No peer_ifindex in interface statistics for %s of container %s", containerInterfaceName, containerDesc)
	}
	peerIfIndex, err := strconv.Atoi(string(match[1]))
	if err != nil { // seems impossible (\d+ not numeric)
		return "", fmt.Errorf("peer_ifindex wasn't numeric: %s: %v", match[1], err)
	}
	iface, err := net.InterfaceByIndex(peerIfIndex)
	if err != nil {
		return "", err
	}
	return iface.Name, nil
}
예제 #5
0
func ExampleWriteIPOSPFHello() {
	var ifs []*net.Interface
	en0, err := net.InterfaceByName("en0")
	if err != nil {
		log.Fatal(err)
	}
	ifs = append(ifs, en0)
	en1, err := net.InterfaceByIndex(911)
	if err != nil {
		log.Fatal(err)
	}
	ifs = append(ifs, en1)

	c, err := net.ListenPacket("ip4:89", "0.0.0.0")
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	r, err := ipv4.NewRawConn(c)
	if err != nil {
		log.Fatal(err)
	}
	for _, ifi := range ifs {
		err := r.JoinGroup(ifi, &net.IPAddr{IP: AllSPFRouters})
		if err != nil {
			log.Fatal(err)
		}
		err = r.JoinGroup(ifi, &net.IPAddr{IP: AllDRouters})
		if err != nil {
			log.Fatal(err)
		}
	}

	hello := make([]byte, OSPFHelloHeaderLen)
	ospf := make([]byte, OSPFHeaderLen)
	ospf[0] = OSPF_VERSION
	ospf[1] = OSPF_TYPE_HELLO
	ospf = append(ospf, hello...)
	iph := &ipv4.Header{}
	iph.Version = ipv4.Version
	iph.Len = ipv4.HeaderLen
	iph.TOS = ipv4.DSCP_CS6
	iph.TotalLen = ipv4.HeaderLen + len(ospf)
	iph.TTL = 1
	iph.Protocol = 89
	iph.Dst = AllSPFRouters

	for _, ifi := range ifs {
		err := r.SetMulticastInterface(ifi)
		if err != nil {
			return
		}
		err = r.WriteTo(iph, ospf, nil)
		if err != nil {
			return
		}
	}
}
예제 #6
0
// IP6ZoneToString converts an IP6 Zone syscall int to a net string
// returns "" if zone is 0
func IP6ZoneToString(zone int) string {
	if zone == 0 {
		return ""
	}
	if ifi, err := net.InterfaceByIndex(zone); err == nil {
		return ifi.Name
	}
	return itod(uint(zone))
}
예제 #7
0
파일: router.go 프로젝트: udhos/nexthop
func udpReader(c *ipv4.PacketConn, input chan<- *udpInfo, ifname string, readerDone chan<- int, listenPort int) {

	log.Printf("udpReader: reading from '%s'", ifname)

	defer c.Close()

	buf := make([]byte, 10000)

LOOP:
	for {
		n, cm, srcAddr, err1 := c.ReadFrom(buf)
		if err1 != nil {
			log.Printf("udpReader: ReadFrom: error %v", err1)
			break LOOP
		}

		var udpSrc *net.UDPAddr

		switch srcAddr.(type) {
		case *net.UDPAddr:
			udpSrc = srcAddr.(*net.UDPAddr)
		}

		var name string

		var ifi *net.Interface
		var err2 error

		if cm != nil {
			ifi, err2 = net.InterfaceByIndex(cm.IfIndex)
			if err2 != nil {
				log.Printf("udpReader: unable to solve ifIndex=%d: error: %v", cm.IfIndex, err2)
			}
		}

		if ifi == nil {
			name = "ifname?"
		} else {
			name = ifi.Name
		}

		udpDst := net.UDPAddr{IP: cm.Dst, Port: listenPort}

		//log.Printf("udpReader: recv %d bytes from %v to %v on %s ifIndex=%d", n, udpSrc, &udpDst, name, cm.IfIndex)

		// make a copy because we will overwrite buf
		b := make([]byte, n)
		copy(b, buf)

		// deliver udp packet to main rip goroutine
		input <- &udpInfo{info: b, src: *udpSrc, dst: udpDst, ifIndex: cm.IfIndex, ifName: name}
	}

	log.Printf("udpReader: exiting '%s' -- trying", ifname)
	readerDone <- 1 // tell rip router goroutine
	log.Printf("udpReader: exiting '%s'", ifname)
}
예제 #8
0
func ipv4MulticastInterface(fd int) (*net.Interface, error) {
	mreqn, err := syscall.GetsockoptIPMreqn(fd, syscall.IPPROTO_IP, syscall.IP_MULTICAST_IF)
	if err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if int(mreqn.Ifindex) == 0 {
		return nil, nil
	}
	return net.InterfaceByIndex(int(mreqn.Ifindex))
}
예제 #9
0
파일: conn.go 프로젝트: NanXiao/tunnel
// Interface returns the associated network interface.
func (c *Conn) Interface() (*net.Interface, error) {
	if !c.ok() {
		return nil, syscall.EINVAL
	}
	ifi, err := net.InterfaceByIndex(c.ifindex)
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
예제 #10
0
func ipv4MulticastInterface(fd int) (*net.Interface, error) {
	mreqn, err := syscall.GetsockoptIPMreqn(fd, ianaProtocolIP, sysSockoptMulticastInterface)
	if err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if mreqn.Ifindex == 0 {
		return nil, nil
	}
	return net.InterfaceByIndex(int(mreqn.Ifindex))
}
예제 #11
0
func ipv6MulticastInterface(fd int) (*net.Interface, error) {
	v, err := syscall.GetsockoptInt(fd, ianaProtocolIPv6, syscall.IPV6_MULTICAST_IF)
	if err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if v == 0 {
		return nil, nil
	}
	ifi, err := net.InterfaceByIndex(v)
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
예제 #12
0
파일: main.go 프로젝트: terual/slimgo
func getMacAddr() (mac [6]uint8, err error) {
	ifaces, _ := net.Interfaces()
	for i := range ifaces {

		iface, err := net.InterfaceByIndex(i + 1)
		if err != nil {
			log.Println(err, i)
			break
		}
		log.Println(iface.HardwareAddr)

	}
	return
}
예제 #13
0
func getsockoptIPMreqn(s uintptr, name int) (*net.Interface, error) {
	var mreqn ipMreqn
	l := uint32(sizeofIPMreqn)
	if err := getsockopt(s, iana.ProtocolIP, name, unsafe.Pointer(&mreqn), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if mreqn.Ifindex == 0 {
		return nil, nil
	}
	ifi, err := net.InterfaceByIndex(int(mreqn.Ifindex))
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
func ipv6MulticastInterface(fd syscall.Handle) (*net.Interface, error) {
	var v int32
	l := int32(4)
	if err := syscall.Getsockopt(fd, int32(ianaProtocolIPv6), int32(syscall.IPV6_MULTICAST_IF), (*byte)(unsafe.Pointer(&v)), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if v == 0 {
		return nil, nil
	}
	ifi, err := net.InterfaceByIndex(int(v))
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
예제 #15
0
파일: endpoints.go 프로젝트: xytis/polyp
//Perform RARP reassign
func broadcastChange(li netlink.Link, en endpoint) error {
	cif, err := net.InterfaceByIndex(li.Attrs().Index)
	if err != nil {
		return fmt.Errorf("could not rediscover interface by index %d (%s): %v", li.Attrs().Index, li.Attrs().Name, err)
	}
	carp, err := arp.NewClient(cif)
	if err != nil {
		return fmt.Errorf("could not bind arp client to interface %s: %v", li.Attrs().Name, err)
	}
	//Broadcast change of ip mac pair
	Log.Infof("Doing broadcast for ip: %v, mac: %v", en.addr, en.mac)
	defer carp.Close()

	return carp.BroadcastChange(en.addr, en.mac)
}
예제 #16
0
func ipv6MulticastInterface(fd int) (*net.Interface, error) {
	var v int32
	l := sysSockoptLen(4)
	if err := getsockopt(fd, ianaProtocolIPv6, sysSockoptMulticastInterface, unsafe.Pointer(&v), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if v == 0 {
		return nil, nil
	}
	ifi, err := net.InterfaceByIndex(int(v))
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
예제 #17
0
func isLocalLinkLocalAddress(ifindex int, addr net.IP) (bool, error) {
	ifi, err := net.InterfaceByIndex(ifindex)
	if err != nil {
		return false, err
	}
	addrs, err := ifi.Addrs()
	if err != nil {
		return false, err
	}
	for _, a := range addrs {
		if ip, _, _ := net.ParseCIDR(a.String()); addr.Equal(ip) {
			return true, nil
		}
	}
	return false, nil
}
예제 #18
0
파일: iface.go 프로젝트: vanloswang/flannel
func GetDefaultGatewayIface() (*net.Interface, error) {
	routes, err := netlink.RouteList(nil, syscall.AF_INET)
	if err != nil {
		return nil, err
	}

	for _, route := range routes {
		if route.Dst == nil || route.Dst.String() == "0.0.0.0/0" {
			if route.LinkIndex <= 0 {
				return nil, errors.New("Found default route but could not determine interface")
			}
			return net.InterfaceByIndex(route.LinkIndex)
		}
	}

	return nil, errors.New("Unable to find default route")
}
예제 #19
0
// getDefaultRouteMtu returns the MTU for the default route's interface.
func getDefaultRouteMtu() (int, error) {
	routes, err := netlink.RouteList(nil, 0)
	if err != nil {
		return 0, err
	}
	for _, r := range routes {
		// a nil Dst means that this is the default route.
		if r.Dst == nil {
			i, err := net.InterfaceByIndex(r.LinkIndex)
			if err != nil {
				continue
			}
			return i.MTU, nil
		}
	}
	return 0, errNoDefaultRoute
}
func getMTUInfo(s uintptr, opt *sockOpt) (*net.Interface, int, error) {
	if opt.name < 1 || opt.typ != ssoTypeMTUInfo {
		return nil, 0, errOpNoSupport
	}
	var mi sysIPv6Mtuinfo
	l := uint32(sysSizeofIPv6Mtuinfo)
	if err := getsockopt(s, opt.level, opt.name, unsafe.Pointer(&mi), &l); err != nil {
		return nil, 0, os.NewSyscallError("getsockopt", err)
	}
	if mi.Addr.Scope_id == 0 {
		return nil, int(mi.Mtu), nil
	}
	ifi, err := net.InterfaceByIndex(int(mi.Addr.Scope_id))
	if err != nil {
		return nil, 0, err
	}
	return ifi, int(mi.Mtu), nil
}
func getInterface(s uintptr, opt *sockOpt) (*net.Interface, error) {
	if opt.name < 1 || opt.typ != ssoTypeInterface {
		return nil, errOpNoSupport
	}
	var i int32
	l := uint32(4)
	if err := getsockopt(s, opt.level, opt.name, unsafe.Pointer(&i), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if i == 0 {
		return nil, nil
	}
	ifi, err := net.InterfaceByIndex(int(i))
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
예제 #22
0
func getInterface(fd syscall.Handle, opt *sockOpt) (*net.Interface, error) {
	if opt.name < 1 || opt.typ != ssoTypeInterface {
		return nil, errOpNoSupport
	}
	var i int32
	l := int32(4)
	if err := syscall.Getsockopt(fd, int32(opt.level), int32(opt.name), (*byte)(unsafe.Pointer(&i)), &l); err != nil {
		return nil, os.NewSyscallError("getsockopt", err)
	}
	if i == 0 {
		return nil, nil
	}
	ifi, err := net.InterfaceByIndex(int(i))
	if err != nil {
		return nil, err
	}
	return ifi, nil
}
예제 #23
0
func main() {
	routes, err := netlink.RouteList(nil, 0)
	if err != nil {
		fmt.Println("netlink.RouteList: ", err)
		return
	}
	for _, r := range routes {
		// a nil Dst means that this is the default route.
		if r.Dst == nil {
			fmt.Println(r)
			i, err := net.InterfaceByIndex(r.LinkIndex)
			if err != nil {
				fmt.Println("net.InterfaceByIndex", r.LinkIndex, err)
				continue
			}
			fmt.Println(i)
			return
		}
	}
	return
}
예제 #24
0
// newNeighbor attempts to parse a netlink message into a Neighbor.
func newNeighbor(m *syscall.NetlinkMessage) (*Neighbor, error) {
	// Gather netlink route attributes from message
	attrs, err := parseNetlinkRouteAttr(m)
	if err != nil {
		return nil, err
	}

	// Iterate attributes in search of values for MAC address and IP
	// address; other values can be inferred by ndmsg struct directly
	var ip net.IP
	var mac net.HardwareAddr
	for _, a := range attrs {
		if a.Attr.Type == ndaDST {
			ip = net.IP(a.Value)
		}

		if a.Attr.Type == ndaLLADDR {
			mac = net.HardwareAddr(a.Value)
		}
	}

	// Cast raw data into a ndmsg struct to obtain more information for
	// a Neighbor
	ndm := (*ndmsg)(unsafe.Pointer(&m.Data[0]))

	// Retrieve local interface designated by index, indicating which interface
	// contacted this neighbor
	ifi, err := net.InterfaceByIndex(int(ndm.IfIndex))
	if err != nil {
		return nil, err
	}

	return &Neighbor{
		Interface:    ifi,
		IP:           ip,
		HardwareAddr: mac,
		Flags:        Flags(ndm.Flags),
		State:        State(ndm.State),
	}, nil
}
예제 #25
0
func GetRouteList(cResp chan<- *Response, rawArgs *json.RawMessage, tag string) {
	args := &struct {
		Family int `json:"family"`
	}{}

	json.Unmarshal(*rawArgs, &args)

	var family int

	switch args.Family {
	case netlink.FAMILY_ALL, netlink.FAMILY_V4, netlink.FAMILY_V6:
		family = args.Family
	}

	rlist, err := netlink.RouteList(nil, family)
	if err != nil {
		cResp <- &Response{nil, tag, NewRTNetlinkError(err)}
		return
	}

	rlist2 := make([]Route, 0, len(rlist))

	for _, r := range rlist {
		link, _ := net.InterfaceByIndex(r.LinkIndex)
		var n IPNet
		if r.Dst != nil {
			n = IPNet(*r.Dst)
		}
		r2 := Route{
			Ifname: link.Name,
			Scope:  r.Scope,
			Dst:    &n,
			Src:    r.Src,
			Gw:     r.Gw,
		}
		rlist2 = append(rlist2, r2)
	}

	cResp <- &Response{rlist2, tag, nil}
}
예제 #26
0
파일: main.go 프로젝트: CodyGuo/Go-Cody
func main() {
	// syscall.GetHostByName("codyguo")
	const maxSiz = 50
	var n uint32 = maxSiz
	buf := make([]uint16, maxSiz)
	syscall.GetComputerName(&buf[0], &n)
	name := syscall.UTF16ToString(buf)
	fmt.Println(name)
	tmp, _ := net.InterfaceByName("以太网")
	tmp2, _ := net.InterfaceByIndex(3)

	inters, _ := net.Interfaces()

	fmt.Println(inters)
	fmt.Println(inters[0])
	fmt.Println(tmp2)
	fmt.Println(tmp)
	type s struct {
		Description string
		SettingID   string
		MACAddress  string
		// ArpAlwaysSourceRoute string
		// ArpUseEtherSNAP  int
		// DefaultIPGateway []string
		// DefaultTOS uint8
		// DHCPEnabled      int
	}
	var dst []s
	err := wmi.Query("SELECT * FROM Win32_NetworkAdapterConfiguration", &dst)
	if err != nil {
		fmt.Println("Expected err field mismatch", err)
		return
	}
	for _, s := range dst {
		fmt.Println(s)
	}
}
예제 #27
0
파일: dhcp.go 프로젝트: erixzone/pixiecore
func InterfaceIP(ifIdx int) (net.IP, error) {
	iface, err := net.InterfaceByIndex(ifIdx)
	if err != nil {
		return nil, err
	}

	addrs, err := iface.Addrs()
	if err != nil {
		return nil, err
	}

	// Try to find an IPv4 address to use, in the following order:
	// global unicast (includes rfc1918), link-local unicast,
	// loopback.
	fs := [](func(net.IP) bool){
		net.IP.IsGlobalUnicast,
		net.IP.IsLinkLocalUnicast,
		net.IP.IsLoopback,
	}
	for _, f := range fs {
		for _, a := range addrs {
			ipaddr, ok := a.(*net.IPNet)
			if !ok {
				continue
			}
			ip := ipaddr.IP.To4()
			if ip == nil {
				continue
			}
			if f(ip) {
				return ip, nil
			}
		}
	}

	return nil, fmt.Errorf("interface %s has no usable unicast addresses", iface.Name)
}
예제 #28
0
func ExampleMulticastUDPListener() {
	en0, err := net.InterfaceByName("en0")
	if err != nil {
		log.Fatal(err)
	}
	en1, err := net.InterfaceByIndex(911)
	if err != nil {
		log.Fatal(err)
	}
	group := net.IPv4(224, 0, 0, 250)

	c, err := net.ListenPacket("udp4", "0.0.0.0:1024")
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	p := ipv4.NewPacketConn(c)
	err = p.JoinGroup(en0, &net.UDPAddr{IP: group})
	if err != nil {
		log.Fatal(err)
	}
	err = p.JoinGroup(en1, &net.UDPAddr{IP: group})
	if err != nil {
		log.Fatal(err)
	}

	err = p.SetControlMessage(ipv4.FlagDst, true)
	if err != nil {
		log.Fatal(err)
	}

	b := make([]byte, 1500)
	for {
		n, cm, src, err := p.ReadFrom(b)
		if err != nil {
			log.Fatal(err)
		}
		if cm.Dst.IsMulticast() {
			if cm.Dst.Equal(group) {
				// joined group, do something
			} else {
				// unknown group, discard
				continue
			}
		}
		p.SetTOS(ipv4.DSCP_CS7)
		p.SetTTL(16)
		_, err = p.WriteTo(b[:n], nil, src)
		if err != nil {
			log.Fatal(err)
		}
		dst := &net.UDPAddr{IP: group, Port: 1024}
		for _, ifi := range []*net.Interface{en0, en1} {
			err := p.SetMulticastInterface(ifi)
			if err != nil {
				log.Fatal(err)
			}
			p.SetMulticastTTL(2)
			_, err = p.WriteTo(b[:n], nil, dst)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	err = p.LeaveGroup(en1, &net.UDPAddr{IP: group})
	if err != nil {
		log.Fatal(err)
	}
	newgroup := net.IPv4(224, 0, 0, 249)
	err = p.JoinGroup(en1, &net.UDPAddr{IP: newgroup})
	if err != nil {
		log.Fatal(err)
	}
}
예제 #29
0
func ExampleIPOSPFListener() {
	var ifs []*net.Interface
	en0, err := net.InterfaceByName("en0")
	if err != nil {
		log.Fatal(err)
	}
	ifs = append(ifs, en0)
	en1, err := net.InterfaceByIndex(911)
	if err != nil {
		log.Fatal(err)
	}
	ifs = append(ifs, en1)

	c, err := net.ListenPacket("ip4:89", "0.0.0.0")
	if err != nil {
		log.Fatal(err)
	}
	defer c.Close()

	r, err := ipv4.NewRawConn(c)
	if err != nil {
		log.Fatal(err)
	}
	for _, ifi := range ifs {
		err := r.JoinGroup(ifi, &net.IPAddr{IP: AllSPFRouters})
		if err != nil {
			log.Fatal(err)
		}
		err = r.JoinGroup(ifi, &net.IPAddr{IP: AllDRouters})
		if err != nil {
			log.Fatal(err)
		}
	}

	err = r.SetControlMessage(ipv4.FlagDst|ipv4.FlagInterface, true)
	if err != nil {
		log.Fatal(err)
	}
	r.SetTOS(ipv4.DSCP_CS6)

	parseOSPFHeader := func(b []byte) *OSPFHeader {
		if len(b) < OSPFHeaderLen {
			return nil
		}
		return &OSPFHeader{
			Version:  b[0],
			Type:     b[1],
			Len:      uint16(b[2])<<8 | uint16(b[3]),
			RouterID: uint32(b[4])<<24 | uint32(b[5])<<16 | uint32(b[6])<<8 | uint32(b[7]),
			AreaID:   uint32(b[8])<<24 | uint32(b[9])<<16 | uint32(b[10])<<8 | uint32(b[11]),
			Checksum: uint16(b[12])<<8 | uint16(b[13]),
		}
	}

	b := make([]byte, 1500)
	for {
		iph, p, _, err := r.ReadFrom(b)
		if err != nil {
			log.Fatal(err)
		}
		if iph.Version != ipv4.Version {
			continue
		}
		if iph.Dst.IsMulticast() {
			if !iph.Dst.Equal(AllSPFRouters) && !iph.Dst.Equal(AllDRouters) {
				continue
			}
		}
		ospfh := parseOSPFHeader(p)
		if ospfh == nil {
			continue
		}
		if ospfh.Version != OSPF_VERSION {
			continue
		}
		switch ospfh.Type {
		case OSPF_TYPE_HELLO:
		case OSPF_TYPE_DB_DESCRIPTION:
		case OSPF_TYPE_LS_REQUEST:
		case OSPF_TYPE_LS_UPDATE:
		case OSPF_TYPE_LS_ACK:
		}
	}
}
예제 #30
0
// Returns an array of IPNet for all the currently routed subnets on ipv4
// This is similar to the first column of "ip route" output
func NetworkGetRoutes() ([]Route, error) {
	native := nativeEndian()

	s, err := getNetlinkSocket()
	if err != nil {
		return nil, err
	}
	defer s.Close()

	wb := newNetlinkRequest(syscall.RTM_GETROUTE, syscall.NLM_F_DUMP)

	msg := newIfInfomsg(syscall.AF_UNSPEC)
	wb.AddData(msg)

	if err := s.Send(wb); err != nil {
		return nil, err
	}

	pid, err := s.GetPid()
	if err != nil {
		return nil, err
	}

	res := make([]Route, 0)

done:
	for {
		msgs, err := s.Receive()
		if err != nil {
			return nil, err
		}
		for _, m := range msgs {
			if m.Header.Seq != wb.Seq {
				return nil, fmt.Errorf("Wrong Seq nr %d, expected 1", m.Header.Seq)
			}
			if m.Header.Pid != pid {
				return nil, fmt.Errorf("Wrong pid %d, expected %d", m.Header.Pid, pid)
			}
			if m.Header.Type == syscall.NLMSG_DONE {
				break done
			}
			if m.Header.Type == syscall.NLMSG_ERROR {
				error := int32(native.Uint32(m.Data[0:4]))
				if error == 0 {
					break done
				}
				return nil, syscall.Errno(-error)
			}
			if m.Header.Type != syscall.RTM_NEWROUTE {
				continue
			}

			var r Route

			msg := (*RtMsg)(unsafe.Pointer(&m.Data[0:syscall.SizeofRtMsg][0]))

			if msg.Flags&syscall.RTM_F_CLONED != 0 {
				// Ignore cloned routes
				continue
			}

			if msg.Table != syscall.RT_TABLE_MAIN {
				// Ignore non-main tables
				continue
			}

			if msg.Family != syscall.AF_INET {
				// Ignore non-ipv4 routes
				continue
			}

			if msg.Dst_len == 0 {
				// Default routes
				r.Default = true
			}

			attrs, err := syscall.ParseNetlinkRouteAttr(&m)
			if err != nil {
				return nil, err
			}
			for _, attr := range attrs {
				switch attr.Attr.Type {
				case syscall.RTA_DST:
					ip := attr.Value
					r.IPNet = &net.IPNet{
						IP:   ip,
						Mask: net.CIDRMask(int(msg.Dst_len), 8*len(ip)),
					}
				case syscall.RTA_OIF:
					index := int(native.Uint32(attr.Value[0:4]))
					r.Iface, _ = net.InterfaceByIndex(index)
				}
			}
			if r.Default || r.IPNet != nil {
				res = append(res, r)
			}
		}
	}

	return res, nil
}