abbel/main.go

152 lines
3.5 KiB
Go
Raw Normal View History

2021-12-08 11:41:29 +01:00
package main
import (
2021-12-16 06:02:42 +01:00
"flag"
2021-12-08 11:41:29 +01:00
"fmt"
"log"
"net/netip"
2021-12-16 06:02:42 +01:00
"strings"
2021-12-08 11:41:29 +01:00
2021-12-14 10:17:05 +01:00
"git.freifunk-franken.de/jkimmel/abbel/packet"
2021-12-08 11:41:29 +01:00
"git.freifunk-franken.de/jkimmel/abbel/tlv"
)
type options struct {
Group string
Port uint16
Ifs []string
2021-12-08 11:41:29 +01:00
}
func parseOpts() (options, error) {
var opt options
var err error
var unusedMulticast bool
2021-12-16 06:02:42 +01:00
flag.StringVar(&opt.Group, "group", "ff02:0:0:0:0:0:1:6", "Multicast group to join")
port := flag.Uint("port", 6696, "Port to listen on")
flag.BoolVar(&unusedMulticast, "m", false, "Use multicast mode (default, unused)")
2021-12-16 06:02:42 +01:00
ifs := flag.String("i", "any", "Comma-seperated list of interfaces to listen on or \"any\" for all interfaces in capture mode")
flag.Parse()
if *port == 0 || *port >= 0xffff {
return options{}, fmt.Errorf("Invalid port %q", *port)
}
opt.Port = uint16(*port)
for _, iface := range strings.Split(*ifs, ",") {
opt.Ifs = append(opt.Ifs, iface)
2021-12-08 11:41:29 +01:00
}
return opt, err
}
2021-12-15 11:20:16 +01:00
type updatesKey struct {
prefix netip.Prefix
2021-12-15 11:20:16 +01:00
routerID tlv.RouterID
nexthop netip.Addr
2021-12-15 11:20:16 +01:00
}
var (
updates = map[updatesKey]tlv.Update{}
)
type BabelPacketConn interface {
ReadFrom(b []byte) (body []byte, src netip.Addr, ifindex int, err error)
2021-12-15 11:20:16 +01:00
Close() error
}
2021-12-08 11:41:29 +01:00
func run(opt options) error {
2021-12-15 11:20:16 +01:00
var err error
var conn BabelPacketConn
conn, err = packet.Listen(opt.Group, opt.Port, opt.Ifs...)
2021-12-08 11:41:29 +01:00
if err != nil {
return err
}
2021-12-14 10:17:05 +01:00
defer conn.Close()
2021-12-08 11:41:29 +01:00
2021-12-13 06:55:52 +01:00
buf := [4096]byte{}
2021-12-14 10:17:05 +01:00
var s tlv.PacketDecoder
2021-12-08 11:41:29 +01:00
for {
2021-12-15 11:20:16 +01:00
b, src, ifindex, err := conn.ReadFrom(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
}
2021-12-14 10:28:17 +01:00
fmt.Print("\x1B[1m")
2021-12-15 11:20:16 +01:00
fmt.Printf("Packet size %4d from %s", len(b), src)
2021-12-14 10:28:17 +01:00
fmt.Println("\x1B[0m")
2021-12-15 11:20:16 +01:00
s.Reset(b, src, ifindex)
2021-12-13 06:55:52 +01:00
for s.Scan() {
switch t := s.TLV().(type) {
case tlv.NextHop:
2021-12-15 11:20:16 +01:00
//fmt.Printf("%12s %s\n", t.T(), t.Address)
2021-12-13 06:55:52 +01:00
case tlv.Hello:
fmt.Printf("% 12s %+v\n", t.T(), t)
2021-12-08 11:41:29 +01:00
case tlv.Update:
2021-12-15 11:20:16 +01:00
key := updatesKey{t.Prefix, t.RouterID, t.NextHop}
tmetric := t.Metric
diff := int(tmetric) - int(updates[key].Metric)
updates[key] = t
if diff == 0 && tmetric != 0xFFFF {
break
}
if t.Metric == 0xFFFF {
fmt.Print("\x1B[31m")
2021-12-08 11:41:29 +01:00
} else {
2021-12-15 11:20:16 +01:00
fmt.Print("\x1B[36m")
2021-12-08 11:41:29 +01:00
}
2023-03-09 10:44:18 +01:00
fmt.Printf("% 12s %-43s%+6d %s\x1B[0m\n", t.T(), t.Prefix, diff, t.FormatHeader())
2021-12-13 06:55:52 +01:00
case tlv.RouterID:
2021-12-15 11:20:16 +01:00
//fmt.Printf("%12s %s\n", t.T(), t)
2021-12-13 06:55:52 +01:00
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:
2023-03-09 10:44:18 +01:00
fmt.Printf("%12s %-43sRxcost %5d Interval %4d\n", t.T(), t.Address, t.Rxcost, t.Interval)
case tlv.SeqnoRequest:
fmt.Printf("%12s %-43sSeqno %5d HopCount %3d RouterID %s\n", t.T(), t.Prefix, t.Seqno, t.HopCount, t.RouterID)
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")
}
}
subtlv := s.SubTLV()
2021-12-13 06:55:52 +01:00
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)
}
}
}
func main() {
opt, err := parseOpts()
if err != nil {
log.Fatal(err)
}
if err := run(opt); err != nil {
log.Fatal(err)
}
}