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") }
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") }
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) }
func benchmarkReadWriteIPv4UDP(b *testing.B, p *ipv4.PacketConn, wb, rb []byte, dst net.Addr, ifi *net.Interface) { cm := ipv4.ControlMessage{TTL: 1} if ifi != nil { cm.IfIndex = ifi.Index } if n, err := p.WriteTo(wb, &cm, dst); err != nil { b.Fatal(err) } else if n != len(wb) { b.Fatalf("got %v; want %v", n, len(wb)) } if _, _, _, err := p.ReadFrom(rb); err != nil { b.Fatal(err) } }
func sender(p *ipv4.PacketConn, dst net.Addr) { ift, err := net.Interfaces() if err != nil { log.Fatal(err) } for i := 0; ; i++ { avail := net.FlagMulticast | net.FlagUp for _, ifi := range ift { if ifi.Flags&avail != avail { continue } p.SetMulticastInterface(&ifi) b := []byte(fmt.Sprintf("#%v HELLLO-R-U-THERE", i)) if _, err := p.WriteTo(b, nil, dst); err != nil { log.Println(err, "on", ifi) continue } log.Printf("%v bytes sent to %v via %v\n", len(b), dst, ifi) time.Sleep(time.Second) } } }
func main() { var flagGroup, flagIP string var flagIndex int var c net.PacketConn var p6 *ipv6.PacketConn var p4 *ipv4.PacketConn iMap = make(map[string]int) flag.BoolVar(&flagList, "li", false, "show available interfaces") flag.IntVar(&flagIndex, "interface", 0, "interface to listen on (number)") flag.StringVar(&flagGroup, "group", "ff02::42:1 239.42.42.1", "multicast groups to join (space seperated)") flag.StringVar(&flagIP, "ip", "", "use interface where the specified ip is bound on") flag.Parse() if flag.NFlag() < 1 { flag.PrintDefaults() os.Exit(1) } if flagList { parseInterfaces() os.Exit(1) } parseInterfaces() if flagIndex == 0 { fmt.Print("searching interface for ip ", flagIP) for k, v := range iMap { if strings.HasPrefix(k, flagIP) { fmt.Println(" using interface", v, "with ip", k) flagIndex = v break } } } fmt.Println("listening on index", flagIndex) iface, err := net.InterfaceByIndex(flagIndex) if err != nil { log.Fatal(err) } groups := strings.Fields(flagGroup) if strings.Contains(flagGroup, ":") { c, err = net.ListenPacket("udp6", "[::]:1024") if err != nil { log.Fatal(err) } defer c.Close() p6 = ipv6.NewPacketConn(c) } if strings.Contains(flagGroup, ".") { c, err = net.ListenPacket("udp4", ":1024") if err != nil { log.Fatal(err) } defer c.Close() p4 = ipv4.NewPacketConn(c) } for _, group := range groups { IPgroup := net.ParseIP(group) if strings.Contains(group, ":") { fmt.Println("joining ipv6 group", group) if err := p6.JoinGroup(iface, &net.UDPAddr{IP: IPgroup}); err != nil { log.Fatal(err) } } else { fmt.Println("joining ipv4 group", group) if err := p4.JoinGroup(iface, &net.UDPAddr{IP: IPgroup}); err != nil { log.Fatal(err) } } } select {} }