From patchwork Wed Aug 19 19:42:43 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andrew Lunn X-Patchwork-Id: 5168 Return-Path: Received: from rubicon.hasler.ascom.ch (rubicon.hasler.ascom.ch [139.79.129.1]) by open-mesh.net (Postfix) with ESMTPS id D90C01543B4 for ; Wed, 19 Aug 2009 20:11:36 +0000 (UTC) Received: from eiger.ma.tech.ascom.ch (eiger.ma.tech.ascom.ch [139.79.100.1]) by rubicon.hasler.ascom.ch (8.14.3/8.14.3) with ESMTP id n7JJghwJ013554; Wed, 19 Aug 2009 21:42:43 +0200 (MEST) Received: from [139.79.100.143] (helo=donkey.ma.tech.ascom.ch) by eiger.ma.tech.ascom.ch with esmtp (Exim 3.16 #1) id 1Mdr3Q-00043H-00; Wed, 19 Aug 2009 21:42:40 +0200 Received: from lunn by donkey.ma.tech.ascom.ch with local (Exim 4.69) (envelope-from ) id 1Mdr3T-0008GT-5r; Wed, 19 Aug 2009 21:42:43 +0200 Date: Wed, 19 Aug 2009 21:42:43 +0200 From: Andrew Lunn To: Sven Eckelmann Message-ID: <20090819194243.GJ20229@ma.tech.ascom.ch> References: <20090819183556.GI20229@ma.tech.ascom.ch> <200908192038.58775.sven.eckelmann@gmx.de> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <200908192038.58775.sven.eckelmann@gmx.de> User-Agent: Mutt/1.5.20 (2009-06-14) Cc: The list for a Better Approach To Mobile Ad-hoc Networking Subject: Re: [B.A.T.M.A.N.] tcpdump patch for batman-adv X-BeenThere: b.a.t.m.a.n@lists.open-mesh.net X-Mailman-Version: 2.1.11 Precedence: list Reply-To: The list for a Better Approach To Mobile Ad-hoc Networking List-Id: The list for a Better Approach To Mobile Ad-hoc Networking List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 19 Aug 2009 20:11:37 -0000 On Wed, Aug 19, 2009 at 08:38:53PM +0200, Sven Eckelmann wrote: > > Attached is a patch for tcpdump which adds support for dissecting > > batman-adv messages. > I think you've forgot to attach it. Grrr. I keep saying i will write an extension to mutt so that it searches for the pattern *[Aa]ttach* and complains if there is none... Andrew diff --git a/Makefile.in b/Makefile.in index 633c59d..cfe9852 100644 --- a/Makefile.in +++ b/Makefile.in @@ -70,6 +70,7 @@ CSRC = addrtoname.c af.c checksum.c cpack.c gmpls.c oui.c gmt2local.c ipproto.c nlpid.c l2vpn.c machdep.c parsenfsfh.c \ print-802_11.c print-ap1394.c print-ah.c print-arcnet.c \ print-aodv.c print-arp.c print-ascii.c print-atalk.c print-atm.c \ + print-batman.c \ print-beep.c print-bfd.c print-bgp.c print-bootp.c print-bt.c \ print-cdp.c print-cfm.c print-chdlc.c print-cip.c print-cnfp.c \ print-dccp.c print-decnet.c \ @@ -115,6 +116,7 @@ HDR = \ arcnet.h \ atm.h \ atmuni31.h \ + batman.h \ bootp.h \ bgp.h \ chdlc.h \ diff --git a/batman.h b/batman.h new file mode 100644 index 0000000..2e802bb --- /dev/null +++ b/batman.h @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2007-2009 B.A.T.M.A.N. contributors: + * Marek Lindner, Simon Wunderlich + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that: (1) source code distributions + * retain the above copyright notice and this paragraph in its entirety, (2) + * distributions including binary code include the above copyright notice and + * this paragraph in its entirety in the documentation or other materials + * provided with the distribution, and (3) all advertising materials mentioning + * features or use of this software display the following acknowledgement: + * ``This product includes software developed by Paolo Abeni.'' + * The name of author may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + */ + +#define ETH_P_BATMAN 0x4305 /* unofficial/not registered Ethertype */ + +#define BAT_PACKET 0x01 +#define BAT_ICMP 0x02 +#define BAT_UNICAST 0x03 +#define BAT_BCAST 0x04 +#define BAT_VIS 0x05 + +/* ICMP message types */ + +#define COMPAT_VERSION 7 + +struct batman_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t flags; +#define DIRECTLINK 0x40 +#define VIS_SERVER 0x20 + uint8_t tq; + uint16_t seqno; + uint8_t orig[6]; + uint8_t old_orig[6]; + uint8_t ttl; + uint8_t num_hna; +} __attribute__((packed)); + +#define BAT_PACKET_LEN sizeof(struct batman_packet) + +struct icmp_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t msg_type; +#define ECHO_REPLY 0 +#define DESTINATION_UNREACHABLE 3 +#define ECHO_REQUEST 8 +#define TTL_EXCEEDED 11 +#define PARAMETER_PROBLEM 12 + uint8_t ttl; + uint8_t dst[6]; + uint8_t orig[6]; + uint16_t seqno; + uint8_t uid; +} __attribute__((packed)); + +struct unicast_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t dest[6]; + uint8_t ttl; +} __attribute__((packed)); + +struct bcast_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t orig[6]; + uint16_t seqno; +} __attribute__((packed)); + +/* vis defines */ +struct vis_packet { + uint8_t packet_type; + uint8_t version; /* batman version field */ + uint8_t vis_type; /* which type of vis-participant sent this? */ +#define VIS_TYPE_SERVER_SYNC 0 +#define VIS_TYPE_CLIENT_UPDATE 1 + uint8_t seqno; /* sequence number */ + uint8_t entries; /* number of entries behind this struct */ + uint8_t ttl; /* TTL */ + uint8_t vis_orig[6]; /* originator that informs about its + * neighbours */ + uint8_t target_orig[6]; /* who should receive this packet */ + uint8_t sender_orig[6]; /* who sent or rebroadcasted this packet */ +} __attribute__((packed)); + +struct vis_info_entry { + uint8_t dest[ETH_ALEN]; + uint8_t quality; /* quality = 0 means HNA */ +} __attribute__((packed)); + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/ethertype.h b/ethertype.h index 900bd38..d8ba023 100644 --- a/ethertype.h +++ b/ethertype.h @@ -61,6 +61,9 @@ #ifndef ETHERTYPE_TRAIL #define ETHERTYPE_TRAIL 0x1000 #endif +#ifndef ETHERTYPE_BATMAN +#define ETHERTYPE_BATMAN 0x4305 /* unofficial/not registered Ethertype */ +#endif #ifndef ETHERTYPE_MOPDL #define ETHERTYPE_MOPDL 0x6001 #endif diff --git a/interface.h b/interface.h index afeaee9..5581496 100644 --- a/interface.h +++ b/interface.h @@ -323,6 +323,7 @@ extern void sip_print(const u_char *, u_int); extern void syslog_print(const u_char *, u_int); extern u_int bt_if_print(const struct pcap_pkthdr *, const u_char *); extern u_int usb_linux_print(const struct pcap_pkthdr *, const u_char *); +extern void batman_print(const u_char *, u_int); #ifdef INET6 extern void ip6_print(const u_char *, u_int); diff --git a/print-batman.c b/print-batman.c new file mode 100644 index 0000000..ccb310e --- /dev/null +++ b/print-batman.c @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2009 Andrew Lunn + +#include +#include +#include +#include + +#include "addrtoname.h" +#include "interface.h" +#include "extract.h" /* must come after interface.h */ +#include "batman.h" + +const struct tok battype2str[] = { + { BAT_PACKET, "OGM" }, + { BAT_ICMP, "ICMP" }, + { BAT_UNICAST, "uni" }, + { BAT_BCAST, "bcast" }, + { BAT_VIS, "VIS" }, + { 0, NULL } +}; + +const struct tok OGM_flags2str[] = { + { DIRECTLINK, "D" }, + { VIS_SERVER, "V" }, + { 0, NULL } +}; + +/* Print an OGM message */ +static void +OGM_print(const u_char *bp, u_int length) +{ + const struct batman_packet *OGM; + const char * orig; + const char * old_orig; + int i; + + if (length < sizeof(struct batman_packet)) { + printf("[|OGM]"); + return; + } + OGM = (struct batman_packet *)bp; + if (OGM->version != 7) { + printf("Unsupported version"); + return; + } + + printf("v7 Flags[%s] tq %d seqno %d ttl %d ", + bittok2str(OGM_flags2str, " ", OGM->flags), + OGM->tq, EXTRACT_16BITS(&OGM->seqno), OGM->ttl); + + orig = etheraddr_string(OGM->orig); + old_orig = etheraddr_string(OGM->old_orig); + printf("orig %s old_orig %s num_hna %d HNAs:", + orig, old_orig, OGM->num_hna); + + /* That was the basic header, now print the HNA list. */ + if ((sizeof(*OGM) + (OGM->num_hna * ETH_ALEN)) > length) { + printf("HNA list truncated"); + return; + } + + bp += sizeof(*OGM); + for (i=0; i < OGM->num_hna; i++) { + printf("%s ", etheraddr_string(bp)); + bp += ETH_ALEN; + } +} + +const struct tok icmptype2str[] = { + { ECHO_REPLY, "reply" }, + { DESTINATION_UNREACHABLE, "unreachable" }, + { ECHO_REQUEST, "request" }, + { TTL_EXCEEDED, "ttl exceeded" }, + { PARAMETER_PROBLEM, "parameter problem" }, + { 0, NULL }, +}; + +/* Print a batman ICMP message */ +static void +bat_ICMP_print(const u_char *bp, u_int length) +{ + const struct icmp_packet * icmp; + const char * orig; + const char * dst; + + if (length < sizeof(struct icmp_packet)) { + printf("[|ICMP]"); + return; + } + icmp = (struct icmp_packet *)bp; + if (icmp->version != 7) { + printf("Unsupported version"); + return; + } + printf("v7 %s", tok2str(icmptype2str, "unknown", icmp->msg_type)); + + orig = etheraddr_string(icmp->orig); + dst = etheraddr_string(icmp->dst); + printf("orig %s dest %d seq %d ttl %d uid %d", + orig, dst, EXTRACT_16BITS(&icmp->seqno), icmp->ttl, + icmp->uid); +} + +/* Print a batman unicast data packet, which includes an encapsulated + ethernet packet */ +static void +unicast_print(const u_char *bp, u_int length) +{ + const struct unicast_packet * unicast; + const char * dest; + + if (length < sizeof(struct unicast_packet)) { + printf("[|unicast]"); + return; + } + unicast = (struct unicast_packet *)bp; + if (unicast->version != 7) { + printf("Unsupported version"); + return; + } + dest = etheraddr_string(unicast->dest); + printf("v7 dest %s ttl %d ", dest, unicast->ttl); + + ether_print(bp+sizeof(*unicast), length - sizeof(*unicast), + length - sizeof(*unicast)); +} + +/* Print a batman broadcast data packet, which includes an encapsulated + ethernet packet */ +static void +bcast_print(const u_char *bp, u_int length) +{ + const struct bcast_packet * bcast; + const char * orig; + + if (length < sizeof(struct bcast_packet)) { + printf("[|bcast]"); + return; + } + bcast = (struct bcast_packet *)bp; + if (bcast->version != 7) { + printf("Unsupported version"); + return; + } + orig = etheraddr_string(bcast->orig); + printf("v7 dest %s ", orig); + + ether_print(bp+sizeof(*bcast), length - sizeof(*bcast), + length - sizeof(*bcast)); +} + +const struct tok vistype2str[] = { + { VIS_TYPE_SERVER_SYNC, "server" }, + { VIS_TYPE_CLIENT_UPDATE, "client" }, + { 0, NULL } +}; + +/* Print a batman visualization packet. */ +static void +vis_print(const u_char *bp, u_int length) +{ + const struct vis_packet * vis; + const struct vis_info_entry * vis_entry; + const char * vis_orig; + const char * target_orig; + const char * sender_orig; + const char * dest; + int i; + + if (length < sizeof(struct vis_packet)) { + printf("[|vis]"); + return; + } + vis = (struct vis_packet *)bp; + if (vis->version != 7) { + printf("Unsupported version"); + return; + } + vis_orig = etheraddr_string(vis->vis_orig); + target_orig = etheraddr_string(vis->target_orig); + sender_orig = etheraddr_string(vis->sender_orig); + + printf("v7 type %s seqno %d entries %d ttl %d ", + tok2str(vistype2str, "unknown", vis->vis_type), + vis->seqno, vis->entries, vis->ttl); + printf("orig %s target %s sender %s VIS:", + vis_orig, target_orig, sender_orig); + + /* That was the header, now the VIS list */ + if ((sizeof(*vis) + (vis->entries * sizeof(*vis_entry))) > length) { + printf("VIS list truncated"); + return; + } + + bp += sizeof(*vis); + for (i=0; i < vis->entries; i++) { + vis_entry = (struct vis_info_entry *)bp; + dest = etheraddr_string(vis_entry->dest); + if (vis_entry->quality == 0) { + printf("[HNA %s]", dest); + } else { + printf("[%s %d]", dest, vis_entry->quality); + } + bp += sizeof(*vis_entry); + } +} + +/* + * print an BATMAN datagram. + */ +void +batman_print(const u_char *bp, u_int length) +{ + if (length < 1) { + (void)printf("truncated-batman %u", length); + return; + } + + printf("batman %s ", tok2str(battype2str, "unknown", *bp)); + + switch (*bp) { + case BAT_PACKET: + OGM_print(bp, length); + break; + case BAT_ICMP: + bat_ICMP_print(bp, length); + break; + case BAT_UNICAST: + unicast_print(bp, length); + break; + case BAT_BCAST: + bcast_print(bp, length); + break; + case BAT_VIS: + vis_print(bp, length); + break; + } +} + +/* + * Local Variables: + * c-style: whitesmith + * c-basic-offset: 8 + * End: + */ diff --git a/print-ether.c b/print-ether.c index 20a2a65..d954ed0 100644 --- a/print-ether.c +++ b/print-ether.c @@ -79,6 +79,7 @@ const struct tok ethertype_values[] = { { ETHERTYPE_CFM_OLD, "CFM (old)" }, { ETHERTYPE_CFM, "CFM" }, { ETHERTYPE_LLDP, "LLDP" }, + { ETHERTYPE_BATMAN, "BATMAN" }, { 0, NULL} }; @@ -335,6 +336,10 @@ ether_encap_print(u_short ether_type, const u_char *p, mpls_print(p, length); return (1); + case ETHERTYPE_BATMAN: + batman_print(p, length); + return (1); + case ETHERTYPE_LAT: case ETHERTYPE_SCA: case ETHERTYPE_MOPRC: