summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CREDITS2
-rw-r--r--Makefile.in6
-rw-r--r--interface.h1
-rw-r--r--print-babel.c422
-rw-r--r--print-udp.c5
-rw-r--r--udp.h1
6 files changed, 432 insertions, 5 deletions
diff --git a/CREDITS b/CREDITS
index 14850b75..eececc03 100644
--- a/CREDITS
+++ b/CREDITS
@@ -69,6 +69,7 @@ Additional people who have contributed patches:
Gert Doering <gert at greenie dot muc dot de>
Greg Minshall <minshall at acm dot org>
Greg Stark <gsstark at mit dot edu>
+ Grégoire Henry <henry@pps.jussieu.fr>
Gilbert Ramirez Jr. <gram at xiexie dot org>
Gisle Vanem <gvanem at broadpark dot no>
Hannes Viertel <hviertel at juniper dot net>
@@ -93,6 +94,7 @@ Additional people who have contributed patches:
Joerg Mayer <jmayer@loplof.de>
Jørgen Thomsen <jth at jth dot net>
Julian Cowley <julian at lava dot net>
+ Juliusz Chroboczek <jch@pps.jussieu.fr>
Kaarthik Sivakumar <kaarthik at torrentnet dot com>
Karl Norby <karl-norby at sourceforge dot net>
Kazushi Sugyo <sugyo at pb dot jp dot nec dot com>
diff --git a/Makefile.in b/Makefile.in
index 1b73a27b..530894b8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -72,9 +72,9 @@ 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-802_15_4.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-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 \
+ print-atm.c print-babel.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 \
print-domain.c print-dtp.c print-dvmrp.c print-enc.c print-egp.c \
print-eap.c print-eigrp.c\
print-esp.c print-ether.c print-fddi.c print-fr.c \
diff --git a/interface.h b/interface.h
index 09da6cb3..aa3954f5 100644
--- a/interface.h
+++ b/interface.h
@@ -324,6 +324,7 @@ extern void ripng_print(const u_char *, unsigned int);
extern int rt6_print(const u_char *, const u_char *);
extern void ospf6_print(const u_char *, u_int);
extern void dhcp6_print(const u_char *, u_int);
+extern void babel_print(const u_char *, u_int);
extern int mask62plen(const u_char *);
#endif /*INET6*/
extern u_short in_cksum(const u_short *, register u_int, int);
diff --git a/print-babel.c b/print-babel.c
new file mode 100644
index 00000000..a8108fc5
--- /dev/null
+++ b/print-babel.c
@@ -0,0 +1,422 @@
+/*
+ * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of the project nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <tcpdump-stdinc.h>
+
+#include <stdio.h>
+#include <string.h>
+
+#include "addrtoname.h"
+#include "interface.h"
+
+static void babel_print_v2(const u_char *cp, u_int length);
+
+void
+babel_print(const u_char *cp, u_int length) {
+ printf("babel");
+
+ TCHECK2(*cp, 4);
+
+ if(cp[0] != 42) {
+ printf(" malformed header");
+ return;
+ } else {
+ printf(" %d", cp[1]);
+ }
+
+ switch(cp[1]) {
+ case 2:
+ babel_print_v2(cp,length);
+ break;
+ default:
+ printf(" unknown version");
+ break;
+ }
+
+ return;
+
+ trunc:
+ printf(" [|babel]");
+ return;
+}
+
+#if defined __GNUC__
+struct __us { unsigned short x __attribute__((packed)); };
+#define DO_NTOHS(_d, _s) \
+ do { _d = ntohs(((const struct __us*)(_s))->x); } while(0)
+#define DO_HTONS(_d, _s) \
+ do { ((struct __us*)(_d))->x = htons(_s); } while(0)
+#else
+#define DO_NTOHS(_d, _s) \
+ do { short _dd; \
+ memcpy(&(_dd), (_s), 2); \
+ _d = ntohs(_dd); } while(0)
+#define DO_HTONS(_d, _s) \
+ do { unsigned short _dd; \
+ _dd = htons(_s); \
+ memcpy((_d), &(_dd), 2); } while(0)
+#endif
+
+#define MESSAGE_PAD1 0
+#define MESSAGE_PADN 1
+#define MESSAGE_ACK_REQ 2
+#define MESSAGE_ACK 3
+#define MESSAGE_HELLO 4
+#define MESSAGE_IHU 5
+#define MESSAGE_ROUTER_ID 6
+#define MESSAGE_NH 7
+#define MESSAGE_UPDATE 8
+#define MESSAGE_REQUEST 9
+#define MESSAGE_MH_REQUEST 10
+
+static const char *
+format_id(const u_char *id)
+{
+ static char buf[25];
+ snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
+ id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]);
+ buf[24] = '\0';
+ return buf;
+}
+
+static const unsigned char v4prefix[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
+
+static const char *
+format_prefix(const u_char *prefix, unsigned char plen)
+{
+ static char buf[50];
+ if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0)
+ snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96);
+ else
+ snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen);
+ buf[49] = '\0';
+ return buf;
+}
+
+static const char *
+format_address(const u_char *prefix)
+{
+ if(memcmp(prefix, v4prefix, 12) == 0)
+ return ipaddr_string(prefix + 12);
+ else
+ return ip6addr_string(prefix);
+}
+
+static int
+network_prefix(int ae, int plen, unsigned int omitted,
+ const unsigned char *p, const unsigned char *dp,
+ unsigned int len, unsigned char *p_r)
+{
+ unsigned pb;
+ unsigned char prefix[16];
+
+ if(plen >= 0)
+ pb = (plen + 7) / 8;
+ else if(ae == 1)
+ pb = 4;
+ else
+ pb = 16;
+
+ if(pb > 16)
+ return -1;
+
+ memset(prefix, 0, 16);
+
+ switch(ae) {
+ case 0: break;
+ case 1:
+ if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
+ return -1;
+ memcpy(prefix, v4prefix, 12);
+ if(omitted) {
+ if (dp == NULL) return -1;
+ memcpy(prefix, dp, 12 + omitted);
+ }
+ if(pb > omitted) memcpy(prefix + 12 + omitted, p, pb - omitted);
+ break;
+ case 2:
+ if(omitted > 16 || (pb > omitted && len < pb - omitted))
+ return -1;
+ if(omitted) {
+ if (dp == NULL) return -1;
+ memcpy(prefix, dp, omitted);
+ }
+ if(pb > omitted) memcpy(prefix + omitted, p, pb - omitted);
+ break;
+ case 3:
+ if(pb > 8 && len < pb - 8) return -1;
+ prefix[0] = 0xfe;
+ prefix[1] = 0x80;
+ if(pb > 8) memcpy(prefix + 8, p, pb - 8);
+ break;
+ default:
+ return -1;
+ }
+
+ memcpy(p_r, prefix, 16);
+ return 1;
+}
+
+static int
+network_address(int ae, const unsigned char *a, unsigned int len,
+ unsigned char *a_r)
+{
+ return network_prefix(ae, -1, 0, a, NULL, len, a_r);
+}
+
+static void
+babel_print_v2(const u_char *cp, u_int length) {
+ int i;
+ u_short bodylen;
+ u_char v4_prefix[16] =
+ {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
+ u_char v6_prefix[16] = {0};
+
+ DO_NTOHS(bodylen, cp + 2);
+ printf(" (%d)", bodylen);
+
+ i = 0;
+ while(i < bodylen) {
+ const u_char *message;
+ u_char type, len;
+
+ TCHECK2(*cp, 4 + i);
+
+ message = cp + 4 + i;
+ type = message[0];
+ len = message[1];
+
+ TCHECK2(*cp, 4 + i + 2 + len);
+
+ switch(type) {
+ case MESSAGE_PAD1: {
+ if(!vflag)
+ printf(" pad1");
+ else
+ printf("\n\tPad 1");
+ }
+ break;
+
+ case MESSAGE_PADN: {
+ if(!vflag)
+ printf(" padN");
+ else
+ printf("\n\tPad %d", len + 2);
+ }
+ break;
+
+ case MESSAGE_ACK_REQ: {
+ u_short nonce, interval;
+ if(!vflag)
+ printf(" ack-req");
+ else {
+ printf("\n\tAcknowledgment Request ");
+ if(len < 6) goto corrupt;
+ DO_NTOHS(nonce, message + 4);
+ DO_NTOHS(interval, message + 6);
+ printf("%04x %d", nonce, interval);
+ }
+ }
+ break;
+
+ case MESSAGE_ACK: {
+ u_short nonce;
+ if(!vflag)
+ printf(" ack");
+ else {
+ printf("\n\tAcknowledgment ");
+ if(len < 2) goto corrupt;
+ DO_NTOHS(nonce, message + 2);
+ printf("%04x", nonce);
+ }
+ }
+ break;
+
+ case MESSAGE_HELLO: {
+ u_short seqno, interval;
+ if(!vflag)
+ printf(" hello");
+ else {
+ printf("\n\tHello ");
+ if(len < 6) goto corrupt;
+ DO_NTOHS(seqno, message + 4);
+ DO_NTOHS(interval, message + 6);
+ printf("seqno %u interval %u", seqno, interval);
+ }
+ }
+ break;
+
+ case MESSAGE_IHU: {
+ unsigned short txcost, interval;
+ if(!vflag)
+ printf(" ihu");
+ else {
+ u_char address[16];
+ int rc;
+ printf("\n\tIHU ");
+ if(len < 6) goto corrupt;
+ DO_NTOHS(txcost, message + 4);
+ DO_NTOHS(interval, message + 6);
+ rc = network_address(message[2], message + 8, len - 6, address);
+ if(rc < 0) { printf("[|babel]"); break; }
+ printf("%s txcost %u interval %d",
+ format_address(address), txcost, interval);
+ }
+ }
+ break;
+
+ case MESSAGE_ROUTER_ID: {
+ if(!vflag)
+ printf(" router-id");
+ else {
+ printf("\n\tRouter Id");
+ if(len < 10) goto corrupt;
+ printf(" %s", format_id(message + 4));
+ }
+ }
+ break;
+
+ case MESSAGE_NH: {
+ if(!vflag)
+ printf(" nh");
+ else {
+ int rc;
+ u_char nh[16];
+ printf("\n\tNext Hop");
+ if(len < 2) goto corrupt;
+ rc = network_address(message[2], message + 4, len - 2, nh);
+ if(rc < 0) goto corrupt;
+ printf(" %s", format_address(nh));
+ }
+ }
+ break;
+
+ case MESSAGE_UPDATE: {
+ if(!vflag) {
+ printf(" update");
+ if(len < 1)
+ printf("/truncated");
+ else
+ printf("%s%s%s",
+ (message[3] & 0x80) ? "/prefix": "",
+ (message[3] & 0x40) ? "/id" : "",
+ (message[3] & 0x3f) ? "/unknown" : "");
+ } else {
+ u_short interval, seqno, metric;
+ u_char plen;
+ int rc;
+ u_char prefix[16];
+ printf("\n\tUpdate");
+ if(len < 10) goto corrupt;
+ plen = message[4] + (message[2] == 1 ? 96 : 0);
+ rc = network_prefix(message[2], message[4], message[5],
+ message + 12,
+ message[2] == 1 ? v4_prefix : v6_prefix,
+ len - 10, prefix);
+ if(rc < 0) goto corrupt;
+ DO_NTOHS(interval, message + 6);
+ DO_NTOHS(seqno, message + 8);
+ DO_NTOHS(metric, message + 10);
+ printf("%s%s%s %s metric %u seqno %u interval %u",
+ (message[3] & 0x80) ? "/prefix": "",
+ (message[3] & 0x40) ? "/id" : "",
+ (message[3] & 0x3f) ? "/unknown" : "",
+ format_prefix(prefix, plen),
+ metric, seqno, interval);
+ if(message[3] & 0x80) {
+ if(message[2] == 1)
+ memcpy(v4_prefix, prefix, 16);
+ else
+ memcpy(v6_prefix, prefix, 16);
+ }
+ }
+ }
+ break;
+
+ case MESSAGE_REQUEST: {
+ if(!vflag)
+ printf(" request");
+ else {
+ int rc;
+ u_char prefix[16], plen;
+ printf("\n\tRequest ");
+ if(len < 2) goto corrupt;
+ plen = message[3] + (message[2] == 1 ? 96 : 0);
+ rc = network_prefix(message[2], message[3], 0,
+ message + 4, NULL, len - 2, prefix);
+ if(rc < 0) goto corrupt;
+ plen = message[3] + (message[2] == 1 ? 96 : 0);
+ printf("for %s",
+ message[2] == 0 ? "any" : format_prefix(prefix, plen));
+ }
+ }
+ break;
+
+ case MESSAGE_MH_REQUEST : {
+ if(!vflag)
+ printf(" mh-request");
+ else {
+ int rc;
+ u_short seqno;
+ u_char prefix[16], plen;
+ printf("\n\tMH-Request ");
+ if(len < 14) goto corrupt;
+ DO_NTOHS(seqno, message + 4);
+ rc = network_prefix(message[2], message[3], 0,
+ message + 16, NULL, len - 14, prefix);
+ if(rc < 0) goto corrupt;
+ plen = message[3] + (message[2] == 1 ? 96 : 0);
+ printf("(%u hops) for %s seqno %u id %s",
+ message[6], format_prefix(prefix, plen),
+ seqno, format_id(message + 8));
+ }
+ }
+ break;
+ default:
+ if(!vflag)
+ printf(" unknown");
+ else
+ printf("\n\tUnknown message type %d", type);
+ }
+ i += len + 2;
+ }
+ return;
+
+ trunc:
+ printf(" [|babel]");
+ return;
+
+ corrupt:
+ printf(" (corrupt)");
+ return;
+}
diff --git a/print-udp.c b/print-udp.c
index d71e4d3a..278d648f 100644
--- a/print-udp.c
+++ b/print-udp.c
@@ -651,9 +651,10 @@ udp_print(register const u_char *bp, u_int length,
#ifdef INET6
else if (ISPORT(RIPNG_PORT))
ripng_print((const u_char *)(up + 1), length);
- else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT)) {
+ else if (ISPORT(DHCP6_SERV_PORT) || ISPORT(DHCP6_CLI_PORT))
dhcp6_print((const u_char *)(up + 1), length);
- }
+ else if (ISPORT(BABEL_PORT))
+ babel_print((const u_char *)(up + 1), length);
#endif /*INET6*/
/*
* Kludge in test for whiteboard packets.
diff --git a/udp.h b/udp.h
index fb45d68f..0dc52273 100644
--- a/udp.h
+++ b/udp.h
@@ -90,4 +90,5 @@ struct udphdr {
#define RIPNG_PORT 521 /*XXX*/
#define DHCP6_SERV_PORT 546 /*XXX*/
#define DHCP6_CLI_PORT 547 /*XXX*/
+#define BABEL_PORT 6697
#endif