############################################################################## # batctl - B.A.T.M.A.N. advanced control and management tool # ############################################################################## Introduction ============ Why do I need batctl ? B.A.T.M.A.N. advanced operates on layer 2 and thus all hosts participating in the virtual switch are completely transparent for all protocols above layer 2. Therefore the common diagnosis tools do not work as expected. To overcome these problems batctl was created. At the moment batctl contains ping, traceroute, tcpdump and interfaces to the kernel module settings. How does it work ? ================== batctl uses the /dev/batman-adv device provided by the B.A.T.M.A.N. advanced kernel module to inject custom icmp packets into the data flow. That's why ping and traceroute work almost like their IP based counterparts. Tcpdump was designed because B.A.T.M.A.N. advanced encapsulates all traffic within batman packets, so that the normal tcpdump would not recognize the packets. The bat-hosts file ================== This file is simliar to the /etc/hosts file. You can write one MAC address and one host name per line. batctl will analyze the file to find the matching MAC address to your provided host name. Host names are much easier to remember than MAC addresses. ;) batctl ping ============ Sends a Layer 2 batman-adv ping to check round trip time and connectivity Usage: batctl ping [options] mac|bat-host options: -c ping packet count -h print this help -i interval in seconds -t timeout in seconds Example: $ batctl ping fe:fe:00:00:09:01 PING fe:fe:00:00:09:01 (fe:fe:00:00:09:01) 19(47) bytes of data 19 bytes from fe:fe:00:00:09:01 icmp_seq=1 ttl=43 time=8.74 ms 19 bytes from fe:fe:00:00:09:01 icmp_seq=2 ttl=43 time=7.48 ms 19 bytes from fe:fe:00:00:09:01 icmp_seq=3 ttl=43 time=8.23 ms ^C--- fe:fe:00:00:09:01 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss rtt min/avg/max/mdev = 7.476/8.151/8.743/1.267 ms batctl traceroute ================== Traceroute sends 3 packets to each hop, awaits the answers and prints out the response times. Usage: batctl traceroute [options] mac|bat-host Example: $ batctl traceroute fe:fe:00:00:09:01 traceroute to fe:fe:00:00:09:01 (fe:fe:00:00:09:01), 50 hops max, 19 byte packets 1: fe:fe:00:00:02:01 4.932 ms 2.338 ms 1.333 ms 2: fe:fe:00:00:03:01 6.860 ms 1.579 ms 1.260 ms 3: fe:fe:00:00:04:01 2.342 ms 1.547 ms 1.655 ms 4: fe:fe:00:00:05:01 2.906 ms 2.211 ms 2.253 ms 5: fe:fe:00:00:06:01 3.577 ms 2.687 ms 3.088 ms 6: fe:fe:00:00:07:01 4.217 ms 5.741 ms 3.551 ms 7: fe:fe:00:00:08:01 5.017 ms 5.547 ms 4.294 ms 8: fe:fe:00:00:09:01 5.730 ms 4.970 ms 6.437 ms batctl tcpdump =============== tcpdump layer 2 traffic on the given interface Usage: batctl tcpdump [options] interface [interface] options: -h print this help -n don't convert addresses to bat-host names -p dump specific packet type 1 - batman ogm packets 2 - batman icmp packets 4 - batman unicast packets 8 - batman broadcast packets 16 - batman vis packets 32 - non batman packets 33 - batman ogm & non batman packets Example output for tcpdump: $ batctl tcpdump mesh0 01:51:42.401188 BAT kansas: OGM via neigh kansas, seqno 6718, tq 255, ttl 50, v 9, flags [..I], length 28 01:51:42.489735 BAT kansas: OGM via neigh wyoming, seqno 6718, tq 245, ttl 49, v 9, flags [.D.], length 28 01:51:42.510330 BAT wyoming: OGM via neigh wyoming, seqno 6721, tq 255, ttl 50, v 9, flags [..I], length 28 01:51:42.601092 BAT wyoming: OGM via neigh kansas, seqno 6721, tq 245, ttl 49, v 9, flags [.D.], length 28 01:51:43.361076 BAT kansas > wyoming: ICMP echo request, id 0, seq 1, ttl 1, v 9, length 19 01:51:43.365347 BAT wyoming > kansas: ICMP echo reply, id 0, seq 1, ttl 50, v 9, length 19 01:51:43.372224 BAT kansas > wyoming: ICMP echo request, id 0, seq 2, ttl 1, v 9, length 19 01:51:43.376506 BAT wyoming > kansas: ICMP echo reply, id 0, seq 2, ttl 50, v 9, length 19 01:51:43.381250 BAT kansas: OGM via neigh kansas, seqno 6719, tq 255, ttl 50, v 9, flags [..I], length 28 01:51:43.386281 BAT kansas > wyoming: ICMP echo request, id 0, seq 3, ttl 1, v 9, length 19 01:51:43.387910 BAT wyoming > kansas: ICMP echo reply, id 0, seq 3, ttl 50, v 9, length 19 01:51:43.479503 BAT kansas: OGM via neigh wyoming, seqno 6719, tq 245, ttl 49, v 9, flags [.D.], length 28 01:51:43.509899 BAT wyoming: OGM via neigh wyoming, seqno 6722, tq 255, ttl 50, v 9, flags [..I], length 28 01:51:43.600999 BAT wyoming: OGM via neigh kansas, seqno 6722, tq 245, ttl 49, v 9, flags [.D.], length 28 01:51:44.381064 BAT kansas: OGM via neigh kansas, seqno 6720, tq 255, ttl 50, v 9, flags [..I], length 28 batctl bisect ============= Analyzes the logfiles to build a small internal database of all sent sequence numbers and routing table changes. This database can be used to search for routing loops (default action), to trace OGMs of a host (use "-t" to specify the mac address or bat-host name) throughout the network or to display routing tables of the nodes (use "-r" to specify the mac address or bat-host name). You can name a specific sequence number or a range using the "-s" option to limit the output's range. Furthermore you can filter the output by specifying an originator (use "-o" to specify the mac address or bat-host name) to only see data connected to this originator. If "-n" was given batctl will not replace the mac addresses with bat-host names in the output. Usage: batctl bisect [options] .. options: -h print this help -l run a loop detection of given mac address or bat-host (default) -n don't convert addresses to bat-host names -r print routing tables of given mac address or bat-host -s seqno range to limit the output -t trace seqnos of given mac address or bat-host Examples: $ batctl bisect log/* -l uml3 Analyzing routing tables of originator: uml3 [all sequence numbers] Checking host: uml3 Path towards uml7 (seqno 9 via neigh uml5): -> uml5 -> uml6 Path towards uml7 (seqno 10 via neigh uml4): -> uml4 -> uml5 -> uml6 Path towards uml6 (seqno 4 via neigh uml4): -> uml4 Path towards uml8 (seqno 12 via neigh uml4): -> uml4 -> uml5 -> uml6 -> uml7 Path towards uml8 (seqno 203 via neigh uml4): -> uml4 -> uml6 -> uml7 Path towards uml8 (seqno 391 via neigh uml2): -> uml2 -> uml3 -> uml2 aborted due to loop! Path towards uml8 (seqno 396 via neigh uml4): -> uml4 -> uml6 -> uml7 Path towards uml9 (seqno 10 via neigh uml5): -> uml5 -> uml6 -> uml7 -> uml9. Path towards uml9 (seqno 10 via neigh uml4): -> uml4 -> uml5 -> uml6 -> uml7 -> uml9. Path towards uml9 (seqno 11 via neigh uml4): -> uml4 -> uml6 -> uml7 -> uml8 -> uml9. Path towards uml9 (seqno 12 via neigh uml4): -> uml4 -> uml5 -> uml6 -> uml7 -> uml8 -> uml9. Path towards uml9 (seqno 21 via neigh uml5): -> uml5 -> uml6 -> uml7 -> uml8 -> uml9. Path towards uml9 (seqno 22 via neigh uml4): -> uml4 -> uml5 -> uml6 -> uml7 -> uml8 -> uml9. $ ./batctl bisect -t uml3 log/* Sequence number flow of originator: uml3 [all sequence numbers] [...] +=> uml3 (seqno 19) |- uml2 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] | |- uml3 [tq: 154, ttl: 49, neigh: uml2, prev_sender: uml3] | \- uml1 [tq: 154, ttl: 49, neigh: uml2, prev_sender: uml3] | |- uml3 [tq: 51, ttl: 48, neigh: uml1, prev_sender: uml2] | \- uml2 [tq: 51, ttl: 48, neigh: uml1, prev_sender: uml2] |- uml5 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] | |- uml6 [tq: 33, ttl: 48, neigh: uml5, prev_sender: uml3] | | |- uml5 [tq: 11, ttl: 47, neigh: uml6, prev_sender: uml5] | | |- uml7 [tq: 11, ttl: 47, neigh: uml6, prev_sender: uml5] | | | |- uml8 [tq: 3, ttl: 46, neigh: uml7, prev_sender: uml6] | | | | |- uml6 [tq: 0, ttl: 45, neigh: uml8, prev_sender: uml7] | | | | |- uml9 [tq: 0, ttl: 45, neigh: uml8, prev_sender: uml7] | | | | \- uml7 [tq: 0, ttl: 45, neigh: uml8, prev_sender: uml7] | | | |- uml6 [tq: 3, ttl: 46, neigh: uml7, prev_sender: uml6] | | | |- uml9 [tq: 3, ttl: 46, neigh: uml7, prev_sender: uml6] | | | \- uml5 [tq: 3, ttl: 46, neigh: uml7, prev_sender: uml6] | | \- uml4 [tq: 11, ttl: 47, neigh: uml6, prev_sender: uml5] | |- uml7 [tq: 33, ttl: 48, neigh: uml5, prev_sender: uml3] | \- uml4 [tq: 33, ttl: 48, neigh: uml5, prev_sender: uml3] \- uml4 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] |- uml3 [tq: 106, ttl: 49, neigh: uml4, prev_sender: uml3] |- uml6 [tq: 106, ttl: 49, neigh: uml4, prev_sender: uml3] |- uml2 [tq: 106, ttl: 49, neigh: uml4, prev_sender: uml3] \- uml5 [tq: 106, ttl: 49, neigh: uml4, prev_sender: uml3] +=> uml3 (seqno 20) |- uml2 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] | |- uml3 [tq: 160, ttl: 49, neigh: uml2, prev_sender: uml3] | |- uml1 [tq: 160, ttl: 49, neigh: uml2, prev_sender: uml3] | \- uml4 [tq: 160, ttl: 49, neigh: uml2, prev_sender: uml3] |- uml5 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] | |- uml3 [tq: 43, ttl: 48, neigh: uml5, prev_sender: uml3] | |- uml6 [tq: 43, ttl: 48, neigh: uml5, prev_sender: uml3] | | |- uml8 [tq: 16, ttl: 47, neigh: uml6, prev_sender: uml5] | | |- uml5 [tq: 16, ttl: 47, neigh: uml6, prev_sender: uml5] | | |- uml7 [tq: 16, ttl: 47, neigh: uml6, prev_sender: uml5] | | | |- uml8 [tq: 5, ttl: 46, neigh: uml7, prev_sender: uml6] | | | | |- uml6 [tq: 0, ttl: 45, neigh: uml8, prev_sender: uml7] | | | | |- uml9 [tq: 0, ttl: 45, neigh: uml8, prev_sender: uml7] | | | | \- uml7 [tq: 0, ttl: 45, neigh: uml8, prev_sender: uml7] | | | \- uml6 [tq: 5, ttl: 46, neigh: uml7, prev_sender: uml6] | | \- uml4 [tq: 16, ttl: 47, neigh: uml6, prev_sender: uml5] | \- uml4 [tq: 43, ttl: 48, neigh: uml5, prev_sender: uml3] |- uml1 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] | \- uml2 [tq: 49, ttl: 48, neigh: uml1, prev_sender: uml3] \- uml4 [tq: 255, ttl: 50, neigh: uml3, prev_sender: uml3] |- uml3 [tq: 114, ttl: 49, neigh: uml4, prev_sender: uml3] |- uml6 [tq: 114, ttl: 49, neigh: uml4, prev_sender: uml3] |- uml2 [tq: 114, ttl: 49, neigh: uml4, prev_sender: uml3] \- uml5 [tq: 114, ttl: 49, neigh: uml4, prev_sender: uml3] [...] batctl originators ================== Check the Originators table Usage: batctl originators|o Example: $ batctl originators Originator (#/255) Nexthop [outgoingIF]: Potential nexthops ... [B.A.T.M.A.N. adv 0.2-beta r1457, MainIF/MAC: eth0/fe:fe:00:00:01:01] fe:fe:00:00:05:01 (223) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:03:01 ( 96) fe:fe:00:00:02:01 (223) fe:fe:00:00:04:01 (233) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:03:01 (100) fe:fe:00:00:02:01 (233) fe:fe:00:00:02:01 (254) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:02:01 (254) fe:fe:00:00:03:01 (100) fe:fe:00:00:07:01 (203) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:02:01 (203) fe:fe:00:00:03:01 ( 88) fe:fe:00:00:08:01 (196) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:03:01 ( 0) fe:fe:00:00:02:01 (196) fe:fe:00:00:03:01 (244) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:03:01 (104) fe:fe:00:00:02:01 (244) fe:fe:00:00:09:01 (184) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:02:01 (184) fe:fe:00:00:03:01 ( 72) fe:fe:00:00:06:01 (214) fe:fe:00:00:02:01 [ eth0]: fe:fe:00:00:03:01 ( 76) fe:fe:00:00:02:01 (214) batctl interface ================ display or modify the interface settings Usage: batctl interface|if [none|interface] Example: $ batctl interface [ active] eth0 fe:fe:00:00:01:01 batctl interval =============== display or modify the originator interval in ms Usage: batctl interval|it [orig_interval] Example: $ batctl interval 1000 batctl log ========== read the log produced by the kernel module Usage: batctl log|l Example: $ batctl log r) [ 400] Received BATMAN packet via NB: fe:fe:00:00:02:01 IF: eth0 [fe:fe:00:00:01:01] (from OG: fe:fe:00:00:01:01 via prev OG: fe:fe:00:00:01:01 seqno 670, tq 245, TTL 49, V 8, IDF 1) [ 400] Drop packet: originator packet from myself (via neighbour) [ 400] Received BATMAN packet via NB: fe:fe:00:00:02:01 IF: eth0 [fe:fe:00:00:01:01] (from OG: fe:fe:00:00:02:01 via prev OG: fe:fe:00:00:02:01 seqno 545, tq 255, TTL 50, V 8, IDF 0) [ 400] updating last_seqno: old 544, new 545 [ 400] bidirectional: orig = fe:fe:00:00:02:01 neigh = fe:fe:00:00:02:01 => own_bcast = 64, real recv = 64, local tq: 255, asym_penalty: 255, total tq: 255 [ 400] update_originator(): Searching and updating originator entry of received packet [ 400] Updating existing last-hop neighbour of originator [...] batctl loglevel =============== display or modify the log level Usage: batctl |ll [level] Example: $ batctl loglevel [x] critical (0) [x] warnings (1) [x] notices (2) [x] batman (4) [x] routes (8) batctl aggregation ================== display or modify the packet aggregation setting Usage: batctl aggregation|ag [0|1] batctl translocal ================= display the local translation table Usage: batctl translocal|tl Example: $ batctl translocal Locally retrieved addresses (from bat0) announced via HNA: * d6:e0:fd:d9:00:00 batctl transglobal ================== display the global translation table Usage: batctl transglobal|tg Example: Globally announced HNAs received via the mesh (translation table): * 16:aa:c4:a2:00:00 via fe:fe:00:00:09:01 * 5a:32:f9:df:00:00 via fe:fe:00:00:03:01 * 32:ae:5a:00:00:00 via fe:fe:00:00:04:01 * 86:88:80:29:00:00 via fe:fe:00:00:08:01 * 9e:d8:72:f2:00:00 via fe:fe:00:00:02:01 * 76:84:68:49:00:00 via fe:fe:00:00:05:01 * 86:4b:b2:d2:00:00 via fe:fe:00:00:07:01 * ca:a1:5b:e5:00:00 via fe:fe:00:00:06:01 batctl vis_server ================= display or modify the status of the VIS server Usage: batctl vis_server|vs [enabled|disabled] Example: $ batctl vis_server [x] client mode (server disabled) [ ] server mode (server enabled) batctl vis_data =============== display the VIS data in dot or JSON format Usage: batctl vis dot {-h}{--no-HNA|-H} {--no-2nd|-2} {--numbers|-n} or batctl vis json {-h}{--no-HNA|-H} {--no-2nd|-2} {--numbers|-n} Example: (A <- 100% -> B,B-if2 <- 50% -> C) $ batctl vis_data dot digraph { "A" -> "B" [label="1.00"] "A" -> "00:ff:f3:cc:68:ac" [label="HNA"] subgraph "cluster_A" { "A" [peripheries=2] } "B" -> "A" [label="1.00"] "B-if2" -> "C" [label="2.00"] "B" -> "22:ff:f3:cc:68:ac" [label="HNA"] subgraph "cluster_B" { "B" [peripheries=2] "B-if2" } "C" -> "B-if2" [label="2.00"] "C" -> "44:ff:f3:cc:68:ac" [label="HNA"] subgraph "cluster_C" { "C" [peripheries=2] } } Explanation: The vis dot (or json) output is adding an entry for each link between two originator's interfaces which are being used for internal routing in batman. The labels are similar/compatible to the ETX metric, 1.0 means perfect connection (100%), 2.0 means 50%, 3.0 means 33% and so on. A host's mac address which is currently connected to the interface of a mesh node (either the mesh node itself or hosts being bridged into the mesh) is being displayed with an "HNA"-label. (--no-hna omits this output) To still have the information about which interfaces belong to which mesh node a subgraph/cluster is being added. The subpgraph is being labeled with a mesh nodes primary interface mac (= Originator MAC). It also has an additional tag [peripheries=2] to make this important MAC address visible, for instance in an image. (--no-2nd omits this output) After the conversion to a png file with graphviz-tools' fdp, all interfaces of a node would be combined in a visual box (see below for details). vis-dot to png -------------- The vis dot output could then further be converted to an image of the topology graph, e.g. with the help of the graphviz-tools. The according commands could then look like this: $ batctl vis_data dot > /tmp/graph.dot $ fdp -Tpng /tmp/graph.dot > graph.png Meaning of the shapes in this image file: * Ellipses: All BATMAN-node and host interfaces can be found in here labeled with the according interface MAC-address. * Boxes: interfaces belonging to one BATMAN-node * double circled interfaces: the primary interface of a BATMAN-node (which is known to other BATMAN-nodes only, except direct neighbours) * Ellipses with an HNA-arrow: mesh clients (this can be a BATMAN-node itself with its bat0 interface or computers/devices being bridged into the mesh) * Arrows with numbers: the transmit quality (in the form 1/TQ) from one BATMAN interface to another BATMAN interface