127 lines
2.2 KiB
Go
127 lines
2.2 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"net"
|
|
|
|
"git.freifunk-franken.de/jkimmel/abbel/tlv"
|
|
"golang.org/x/net/ipv6"
|
|
)
|
|
|
|
type options struct {
|
|
Group net.IP
|
|
Port uint16
|
|
Ifs []net.Interface
|
|
}
|
|
|
|
func parseOpts() (options, error) {
|
|
var opt options
|
|
var err error
|
|
|
|
opt.Group = net.ParseIP("ff02::1:6")
|
|
opt.Port = 6696
|
|
ifi, err := net.InterfaceByName("babel")
|
|
if err != nil {
|
|
return opt, err
|
|
}
|
|
opt.Ifs = []net.Interface{*ifi}
|
|
|
|
return opt, err
|
|
}
|
|
|
|
func run(opt options) error {
|
|
var err error
|
|
uc, err := net.ListenUDP("udp6", &net.UDPAddr{Port: int(opt.Port)})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer uc.Close()
|
|
up := ipv6.NewPacketConn(uc)
|
|
|
|
if err := up.SetControlMessage(ipv6.FlagDst, true); err != nil {
|
|
return err
|
|
}
|
|
|
|
for ifi := range opt.Ifs {
|
|
if err := up.JoinGroup(&opt.Ifs[ifi], &net.UDPAddr{IP: opt.Group}); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
b := make([]byte, 1500)
|
|
for {
|
|
n, rcm, src, err := up.ReadFrom(b)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_ = rcm
|
|
|
|
magic := b[0]
|
|
version := b[1]
|
|
length := uint16(b[2])<<8 + uint16(b[3])
|
|
|
|
if magic != 42 {
|
|
continue
|
|
}
|
|
if int(length)+4 > n {
|
|
fmt.Println("invalid length")
|
|
}
|
|
|
|
fmt.Println(src, rcm, magic, version, length, n)
|
|
|
|
var u tlv.PacketUpdate
|
|
var s tlv.PacketDecoder
|
|
ts := tlv.NewTLVScanner(b[4 : 4+length])
|
|
for ts.Scan() {
|
|
t, v := ts.TLV()
|
|
switch t {
|
|
case tlv.Update:
|
|
u, err = s.UpdateFromBytes(v)
|
|
if err != nil {
|
|
fmt.Println(u.PacketUpdateHeader, &u.Prefix, err)
|
|
} else {
|
|
if u.PacketUpdateHeader.Metric == 0xFFFF {
|
|
fmt.Print("\x1B[1m")
|
|
}
|
|
fmt.Printf("%43s: %+v\x1B[0m\n", &u.Prefix, u.PacketUpdateHeader)
|
|
}
|
|
default:
|
|
fmt.Printf(" T: %12s (%2d), L: %3d\n", t, t, len(v))
|
|
}
|
|
|
|
}
|
|
if ts.Err() != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
//{
|
|
// var bbuf bytes.Buffer
|
|
// lzww := lzw.NewWriter(&bbuf, lzw.LSB, 8)
|
|
// lzww.Write(b[:n])
|
|
// lzww.Close()
|
|
// fmt.Println(n, len(bbuf.Bytes()))
|
|
//}
|
|
//{
|
|
// var bbuf bytes.Buffer
|
|
// gzw, _ := gzip.NewWriterLevel(&bbuf, 9)
|
|
// gzw.Write(b[:n])
|
|
// gzw.Close()
|
|
// fmt.Println(n, len(bbuf.Bytes()))
|
|
//}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
opt, err := parseOpts()
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
if err := run(opt); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
}
|