2021-12-08 11:41:29 +01:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"net"
|
|
|
|
|
|
|
|
"git.freifunk-franken.de/jkimmel/abbel/tlv"
|
|
|
|
"golang.org/x/net/ipv6"
|
2021-12-13 06:55:52 +01:00
|
|
|
"inet.af/netaddr"
|
2021-12-08 11:41:29 +01:00
|
|
|
)
|
|
|
|
|
|
|
|
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
|
|
|
|
}
|
|
|
|
|
2021-12-13 06:55:52 +01:00
|
|
|
func readBabelPacket(up *ipv6.PacketConn, b []byte) ([]byte, netaddr.IP, error) {
|
|
|
|
n, rcm, src, err := up.ReadFrom(b)
|
|
|
|
if err != nil {
|
|
|
|
return nil, netaddr.IP{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
_ = rcm
|
|
|
|
|
|
|
|
b = b[:n]
|
|
|
|
if len(b) < 4 {
|
|
|
|
fmt.Println("packet too short:", len(b))
|
|
|
|
}
|
|
|
|
magic := b[0]
|
|
|
|
version := b[1]
|
|
|
|
length := uint16(b[2])<<8 + uint16(b[3])
|
|
|
|
b = b[4:]
|
|
|
|
|
|
|
|
if magic != 42 {
|
|
|
|
return nil, netaddr.IP{}, fmt.Errorf("Invalid magic number %d", magic)
|
|
|
|
}
|
|
|
|
if int(length) > len(b) {
|
|
|
|
fmt.Println("invalid length:", length)
|
|
|
|
}
|
|
|
|
|
|
|
|
fmt.Println(src, rcm, magic, version, length, n)
|
|
|
|
srcipport, err := netaddr.ParseIPPort(src.String())
|
|
|
|
return b, srcipport.IP(), err
|
|
|
|
}
|
|
|
|
|
2021-12-08 11:41:29 +01:00
|
|
|
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
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-12-13 06:55:52 +01:00
|
|
|
buf := [4096]byte{}
|
2021-12-08 11:41:29 +01:00
|
|
|
for {
|
2021-12-13 06:55:52 +01:00
|
|
|
b, src, err := readBabelPacket(up, buf[:])
|
2021-12-08 11:41:29 +01:00
|
|
|
if err != nil {
|
2021-12-13 06:55:52 +01:00
|
|
|
fmt.Println("Skipping packet:", err)
|
2021-12-08 11:41:29 +01:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
var s tlv.PacketDecoder
|
2021-12-13 06:55:52 +01:00
|
|
|
s.Reset(b, src)
|
|
|
|
for s.Scan() {
|
|
|
|
var subtlv []byte
|
|
|
|
switch t := s.TLV().(type) {
|
|
|
|
case tlv.NextHop:
|
|
|
|
fmt.Printf("%12s %s\n", t.T(), t.Address)
|
|
|
|
case tlv.Hello:
|
|
|
|
fmt.Printf("% 12s %+v\n", t.T(), t)
|
2021-12-08 11:41:29 +01:00
|
|
|
case tlv.Update:
|
|
|
|
if err != nil {
|
2021-12-13 06:55:52 +01:00
|
|
|
fmt.Println(t, t.Prefix, err)
|
2021-12-08 11:41:29 +01:00
|
|
|
} else {
|
2021-12-13 06:55:52 +01:00
|
|
|
if t.Metric == 0xFFFF {
|
|
|
|
fmt.Print("\x1B[31m")
|
|
|
|
} else {
|
|
|
|
fmt.Print("\x1B[36m")
|
2021-12-08 11:41:29 +01:00
|
|
|
}
|
2021-12-13 06:55:52 +01:00
|
|
|
fmt.Printf("% 12s %-43s%s\x1B[0m\n", t.T(), t.Prefix, t.FormatHeader())
|
2021-12-08 11:41:29 +01:00
|
|
|
}
|
2021-12-13 06:55:52 +01:00
|
|
|
case tlv.RouterID:
|
|
|
|
fmt.Printf("%12s %s\n", t.T(), t)
|
|
|
|
case tlv.RouteRequest:
|
|
|
|
fmt.Printf("%12s %s\n", t.T(), t.Prefix)
|
|
|
|
case tlv.Raw:
|
|
|
|
fmt.Printf(" T: %12s (%2d), L: %3d\n", t.T(), t.T(), len(t.V()))
|
|
|
|
case tlv.IHU:
|
|
|
|
fmt.Printf("%12s %-43sRxcost %5d Interval %4d \n", t.T(), t.Address, t.Rxcost, t.Interval)
|
2021-12-08 11:41:29 +01:00
|
|
|
default:
|
2021-12-13 06:55:52 +01:00
|
|
|
if t != nil {
|
|
|
|
fmt.Println("Unknown TLV", t.T(), t)
|
|
|
|
} else {
|
|
|
|
fmt.Println("got nil TLV")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for len(subtlv) > 0 {
|
|
|
|
switch tlv.SubType(subtlv[0]) {
|
|
|
|
case tlv.SubTypeSourcePrefix:
|
|
|
|
var pfx tlv.SourcePrefix
|
|
|
|
pfx, subtlv, err = tlv.SourcePrefixFromBytes(subtlv[2:])
|
|
|
|
fmt.Print("\x1B[7;36m")
|
|
|
|
fmt.Printf("%12s %s\x1B[0m\n", pfx.T(), pfx)
|
|
|
|
case tlv.SubTypeDiversity, tlv.SubTypePad1, tlv.SubTypePadN, tlv.SubTypeTimestamp:
|
|
|
|
fmt.Print("\x1B[7m")
|
|
|
|
fmt.Printf("%12s: %v\x1B[0m\n", "Subtlv", subtlv)
|
|
|
|
subtlv = nil
|
|
|
|
default:
|
|
|
|
panic("unknown subtlv type")
|
|
|
|
}
|
2021-12-08 11:41:29 +01:00
|
|
|
}
|
|
|
|
}
|
2021-12-13 06:55:52 +01:00
|
|
|
if s.Err() != nil {
|
2021-12-08 11:41:29 +01:00
|
|
|
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()))
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
opt, err := parseOpts()
|
|
|
|
if err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
if err := run(opt); err != nil {
|
|
|
|
log.Fatal(err)
|
|
|
|
}
|
|
|
|
}
|