153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Copyright (c) 2007-2011 Grégoire Henry, Juliusz Chroboczek
353f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Redistribution and use in source and binary forms, with or without
553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * modification, are permitted provided that the following conditions
653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * are met:
753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * 1. Redistributions of source code must retain the above copyright
853f17a9db278d33517d9888dd77848f554522a38JP Abgrall *    notice, this list of conditions and the following disclaimer.
953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * 2. Redistributions in binary form must reproduce the above copyright
1053f17a9db278d33517d9888dd77848f554522a38JP Abgrall *    notice, this list of conditions and the following disclaimer in the
1153f17a9db278d33517d9888dd77848f554522a38JP Abgrall *    documentation and/or other materials provided with the distribution.
1253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * 3. Neither the name of the project nor the names of its contributors
1353f17a9db278d33517d9888dd77848f554522a38JP Abgrall *    may be used to endorse or promote products derived from this software
1453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *    without specific prior written permission.
1553f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
1653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
1753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
2053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * SUCH DAMAGE.
2753f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
2853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef HAVE_CONFIG_H
3053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "config.h"
3153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
3253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <tcpdump-stdinc.h>
3453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <stdio.h>
3653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <string.h>
3753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "addrtoname.h"
3953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "interface.h"
4053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "extract.h"
4153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic void babel_print_v2(const u_char *cp, u_int length);
4353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4453f17a9db278d33517d9888dd77848f554522a38JP Abgrallvoid
4553f17a9db278d33517d9888dd77848f554522a38JP Abgrallbabel_print(const u_char *cp, u_int length) {
4653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf("babel");
4753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    TCHECK2(*cp, 4);
4953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
5053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if(cp[0] != 42) {
5153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        printf(" malformed header");
5253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return;
5353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    } else {
5453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        printf(" %d", cp[1]);
5553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
5653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
5753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    switch(cp[1]) {
5853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case 2:
5953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        babel_print_v2(cp,length);
6053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
6153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    default:
6253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        printf(" unknown version");
6353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
6453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
6553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
6753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6853f17a9db278d33517d9888dd77848f554522a38JP Abgrall trunc:
6953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf(" [|babel]");
7053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
7153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
7253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
7353f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* TLVs */
7453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_PAD1 0
7553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_PADN 1
7653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_ACK_REQ 2
7753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_ACK 3
7853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_HELLO 4
7953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_IHU 5
8053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_ROUTER_ID 6
8153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_NH 7
8253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_UPDATE 8
8353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_REQUEST 9
8453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_MH_REQUEST 10
8553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_TSPC 11
8653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_HMAC 12
8753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
8853f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* sub-TLVs */
8953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_SUB_PAD1 0
9053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_SUB_PADN 1
9153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define MESSAGE_SUB_DIVERSITY 2
9253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
9353f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* Diversity sub-TLV channel codes */
9453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok diversity_str[] = {
9553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0,   "reserved" },
9653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 255, "all"      },
9753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL }
9853f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
9953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
10053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const char *
10153f17a9db278d33517d9888dd77848f554522a38JP Abgrallformat_id(const u_char *id)
10253f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
10353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    static char buf[25];
10453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    snprintf(buf, 25, "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x",
10553f17a9db278d33517d9888dd77848f554522a38JP Abgrall             id[0], id[1], id[2], id[3], id[4], id[5], id[6], id[7]);
10653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    buf[24] = '\0';
10753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return buf;
10853f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
10953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
11053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const unsigned char v4prefix[16] =
11153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
11253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
11353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const char *
11453f17a9db278d33517d9888dd77848f554522a38JP Abgrallformat_prefix(const u_char *prefix, unsigned char plen)
11553f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
11653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    static char buf[50];
11753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if(plen >= 96 && memcmp(prefix, v4prefix, 12) == 0)
11853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buf, 50, "%s/%u", ipaddr_string(prefix + 12), plen - 96);
11953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    else
12053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef INET6
12153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buf, 50, "%s/%u", ip6addr_string(prefix), plen);
12253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#else
12353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        snprintf(buf, 50, "IPv6 addresses not supported");
12453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
12553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    buf[49] = '\0';
12653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return buf;
12753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
12853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
12953f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const char *
13053f17a9db278d33517d9888dd77848f554522a38JP Abgrallformat_address(const u_char *prefix)
13153f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if(memcmp(prefix, v4prefix, 12) == 0)
13353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return ipaddr_string(prefix + 12);
13453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    else
13553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef INET6
13653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return ip6addr_string(prefix);
13753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#else
13853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return "IPv6 addresses not supported";
13953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
14053f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
14153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const char *
14353f17a9db278d33517d9888dd77848f554522a38JP Abgrallformat_interval(const u_int16_t i)
14453f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
14553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    static char buf[sizeof("0000.0s")];
14653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (i == 0)
14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return "0.0s (bogus)";
14953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    snprintf(buf, sizeof(buf), "%u.%us", i / 10, i % 10);
15053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return buf;
15153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
15253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15353f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const char *
15453f17a9db278d33517d9888dd77848f554522a38JP Abgrallformat_interval_update(const u_int16_t i)
15553f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
15653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return i == 0xFFFF ? "infinity" : format_interval(i);
15753f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
15853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15953f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* Return number of octets consumed from the input buffer (not the prefix length
16053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * in bytes), or -1 for encoding error. */
16153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
16253f17a9db278d33517d9888dd77848f554522a38JP Abgrallnetwork_prefix(int ae, int plen, unsigned int omitted,
16353f17a9db278d33517d9888dd77848f554522a38JP Abgrall               const unsigned char *p, const unsigned char *dp,
16453f17a9db278d33517d9888dd77848f554522a38JP Abgrall               unsigned int len, unsigned char *p_r)
16553f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
16653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    unsigned pb;
16753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    unsigned char prefix[16];
16853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    int consumed = 0;
16953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if(plen >= 0)
17153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        pb = (plen + 7) / 8;
17253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    else if(ae == 1)
17353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        pb = 4;
17453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    else
17553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        pb = 16;
17653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if(pb > 16)
17853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return -1;
17953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    memset(prefix, 0, 16);
18153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    switch(ae) {
18353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case 0: break;
18453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case 1:
18553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(omitted > 4 || pb > 4 || (pb > omitted && len < pb - omitted))
18653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            return -1;
18753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        memcpy(prefix, v4prefix, 12);
18853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(omitted) {
18953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (dp == NULL) return -1;
19053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            memcpy(prefix, dp, 12 + omitted);
19153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
19253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(pb > omitted) {
19353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            memcpy(prefix + 12 + omitted, p, pb - omitted);
19453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            consumed = pb - omitted;
19553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
19653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
19753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case 2:
19853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(omitted > 16 || (pb > omitted && len < pb - omitted))
19953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            return -1;
20053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(omitted) {
20153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (dp == NULL) return -1;
20253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            memcpy(prefix, dp, omitted);
20353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
20453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(pb > omitted) {
20553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            memcpy(prefix + omitted, p, pb - omitted);
20653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            consumed = pb - omitted;
20753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
20853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
20953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    case 3:
21053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(pb > 8 && len < pb - 8) return -1;
21153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        prefix[0] = 0xfe;
21253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        prefix[1] = 0x80;
21353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(pb > 8) {
21453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            memcpy(prefix + 8, p, pb - 8);
21553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            consumed = pb - 8;
21653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
21753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        break;
21853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    default:
21953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return -1;
22053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
22153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
22253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    memcpy(p_r, prefix, 16);
22353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return consumed;
22453f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
22553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
22653f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic int
22753f17a9db278d33517d9888dd77848f554522a38JP Abgrallnetwork_address(int ae, const unsigned char *a, unsigned int len,
22853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                unsigned char *a_r)
22953f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
23053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return network_prefix(ae, -1, 0, a, NULL, len, a_r);
23153f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
23253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
23353f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
23453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Sub-TLVs consume the "extra data" of Babel TLVs (see Section 4.3 of RFC6126),
23553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * their encoding is similar to the encoding of TLVs, but the type namespace is
23653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * different:
23753f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
23853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * o Type 0 stands for Pad1 sub-TLV with the same encoding as the Pad1 TLV.
23953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * o Type 1 stands for PadN sub-TLV with the same encoding as the PadN TLV.
24053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * o Type 2 stands for Diversity sub-TLV, which propagates diversity routing
24153f17a9db278d33517d9888dd77848f554522a38JP Abgrall *   data. Its body is a variable-length sequence of 8-bit unsigned integers,
24253f17a9db278d33517d9888dd77848f554522a38JP Abgrall *   each representing per-hop number of interferring radio channel for the
24353f17a9db278d33517d9888dd77848f554522a38JP Abgrall *   prefix. Channel 0 is invalid and must not be used in the sub-TLV, channel
24453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *   255 interferes with any other channel.
24553f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
24653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Sub-TLV types 0 and 1 are valid for any TLV type, whether sub-TLV type 2 is
24753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * only valid for TLV type 8 (Update). Note that within an Update TLV a missing
24853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Diversity sub-TLV is not the same as a Diversity sub-TLV with an empty body.
24953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * The former would mean a lack of any claims about the interference, and the
25053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * latter would state that interference is definitely absent. */
25153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic void
25253f17a9db278d33517d9888dd77848f554522a38JP Abgrallsubtlvs_print(const u_char *cp, const u_char *ep, const uint8_t tlv_type) {
25353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    uint8_t subtype, sublen;
25453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const char *sep;
25553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
25653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    while (cp < ep) {
25753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        subtype = *cp++;
25853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(subtype == MESSAGE_SUB_PAD1) {
25953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            printf(" sub-pad1");
26053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            continue;
26153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
26253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(cp == ep)
26353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            goto corrupt;
26453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        sublen = *cp++;
26553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if(cp + sublen > ep)
26653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            goto corrupt;
26753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
26853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        switch(subtype) {
26953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_SUB_PADN:
27053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            printf(" sub-padn");
27153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            cp += sublen;
27253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
27353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_SUB_DIVERSITY:
27453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            printf(" sub-diversity");
27553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (sublen == 0) {
27653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" empty");
27753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                break;
27853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
27953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            sep = " ";
28053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            while(sublen--) {
28153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("%s%s", sep, tok2str(diversity_str, "%u", *cp++));
28253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                sep = "-";
28353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
28453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(tlv_type != MESSAGE_UPDATE)
28553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" (bogus)");
28653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
28753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
28853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            printf(" sub-unknown-0x%02x", subtype);
28953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            cp += sublen;
29053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        } /* switch */
29153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    } /* while */
29253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
29353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
29453f17a9db278d33517d9888dd77848f554522a38JP Abgrall corrupt:
29553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf(" (corrupt)");
29653f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
29753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
29853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define ICHECK(i, l) \
29953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	if ((i) + (l) > bodylen || (i) + (l) > length) goto corrupt;
30053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic void
30253f17a9db278d33517d9888dd77848f554522a38JP Abgrallbabel_print_v2(const u_char *cp, u_int length) {
30353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int i;
30453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_short bodylen;
30553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_char v4_prefix[16] =
30653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0, 0, 0, 0 };
30753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_char v6_prefix[16] = {0};
30853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
30953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    TCHECK2(*cp, 4);
31053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (length < 4)
31153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        goto corrupt;
31253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    bodylen = EXTRACT_16BITS(cp + 2);
31353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf(" (%u)", bodylen);
31453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
31553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* Process the TLVs in the body */
31653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    i = 0;
31753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    while(i < bodylen) {
31853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        const u_char *message;
31953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        u_int type, len;
32053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
32153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        message = cp + 4 + i;
32253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
32353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        TCHECK2(*message, 1);
32453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if((type = message[0]) == MESSAGE_PAD1) {
32553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            printf(vflag ? "\n\tPad 1" : " pad1");
32653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            i += 1;
32753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            continue;
32853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
32953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
33053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        TCHECK2(*message, 2);
33153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ICHECK(i, 2);
33253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        len = message[1];
33353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
33453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        TCHECK2(*message, 2 + len);
33553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        ICHECK(i, 2 + len);
33653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
33753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        switch(type) {
33853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_PADN: {
33953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
34053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" padN");
34153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else
34253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tPad %d", len + 2);
34353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
34453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
34553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
34653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_ACK_REQ: {
34753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            u_short nonce, interval;
34853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
34953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" ack-req");
35053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
35153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tAcknowledgment Request ");
35253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 6) goto corrupt;
35353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                nonce = EXTRACT_16BITS(message + 4);
35453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                interval = EXTRACT_16BITS(message + 6);
35553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("%04x %s", nonce, format_interval(interval));
35653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
35753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
35853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
35953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
36053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_ACK: {
36153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            u_short nonce;
36253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
36353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" ack");
36453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
36553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tAcknowledgment ");
36653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 2) goto corrupt;
36753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                nonce = EXTRACT_16BITS(message + 2);
36853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("%04x", nonce);
36953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
37053f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
37153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
37253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
37353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_HELLO:  {
37453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            u_short seqno, interval;
37553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
37653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" hello");
37753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
37853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tHello ");
37953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 6) goto corrupt;
38053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                seqno = EXTRACT_16BITS(message + 4);
38153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                interval = EXTRACT_16BITS(message + 6);
38253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("seqno %u interval %s", seqno, format_interval(interval));
38353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
38453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
38553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
38653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
38753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_IHU: {
38853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            unsigned short txcost, interval;
38953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
39053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" ihu");
39153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
39253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_char address[16];
39353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                int rc;
39453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tIHU ");
39553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 6) goto corrupt;
39653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                txcost = EXTRACT_16BITS(message + 4);
39753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                interval = EXTRACT_16BITS(message + 6);
39853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                rc = network_address(message[2], message + 8, len - 6, address);
39953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(rc < 0) { printf("[|babel]"); break; }
40053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("%s txcost %u interval %s",
40153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       format_address(address), txcost, format_interval(interval));
40253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
40353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
40453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
40553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
40653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_ROUTER_ID: {
40753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
40853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" router-id");
40953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
41053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tRouter Id");
41153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 10) goto corrupt;
41253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" %s", format_id(message + 4));
41353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
41453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
41553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
41653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
41753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_NH: {
41853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
41953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" nh");
42053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
42153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                int rc;
42253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_char nh[16];
42353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tNext Hop");
42453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 2) goto corrupt;
42553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                rc = network_address(message[2], message + 4, len - 2, nh);
42653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(rc < 0) goto corrupt;
42753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" %s", format_address(nh));
42853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
42953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
43053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
43153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
43253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_UPDATE: {
43353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag) {
43453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" update");
43553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 1)
43653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    printf("/truncated");
43753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                else
43853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    printf("%s%s%s",
43953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           (message[3] & 0x80) ? "/prefix": "",
44053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           (message[3] & 0x40) ? "/id" : "",
44153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                           (message[3] & 0x3f) ? "/unknown" : "");
44253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            } else {
44353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_short interval, seqno, metric;
44453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_char plen;
44553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                int rc;
44653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_char prefix[16];
44753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tUpdate");
44853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 10) goto corrupt;
44953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                plen = message[4] + (message[2] == 1 ? 96 : 0);
45053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                rc = network_prefix(message[2], message[4], message[5],
45153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                    message + 12,
45253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                    message[2] == 1 ? v4_prefix : v6_prefix,
45353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                    len - 10, prefix);
45453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(rc < 0) goto corrupt;
45553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                interval = EXTRACT_16BITS(message + 6);
45653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                seqno = EXTRACT_16BITS(message + 8);
45753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                metric = EXTRACT_16BITS(message + 10);
45853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("%s%s%s %s metric %u seqno %u interval %s",
45953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       (message[3] & 0x80) ? "/prefix": "",
46053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       (message[3] & 0x40) ? "/id" : "",
46153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       (message[3] & 0x3f) ? "/unknown" : "",
46253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       format_prefix(prefix, plen),
46353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       metric, seqno, format_interval_update(interval));
46453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(message[3] & 0x80) {
46553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    if(message[2] == 1)
46653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        memcpy(v4_prefix, prefix, 16);
46753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    else
46853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                        memcpy(v6_prefix, prefix, 16);
46953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                }
47053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                /* extra data? */
47153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if((u_int)rc < len - 10)
47253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    subtlvs_print(message + 12 + rc, message + 2 + len, type);
47353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
47453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
47553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
47653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
47753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_REQUEST: {
47853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
47953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" request");
48053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
48153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                int rc;
48253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_char prefix[16], plen;
48353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tRequest ");
48453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 2) goto corrupt;
48553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                plen = message[3] + (message[2] == 1 ? 96 : 0);
48653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                rc = network_prefix(message[2], message[3], 0,
48753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                    message + 4, NULL, len - 2, prefix);
48853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(rc < 0) goto corrupt;
48953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                plen = message[3] + (message[2] == 1 ? 96 : 0);
49053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("for %s",
49153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       message[2] == 0 ? "any" : format_prefix(prefix, plen));
49253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
49353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
49453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
49553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
49653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_MH_REQUEST : {
49753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
49853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" mh-request");
49953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
50053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                int rc;
50153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_short seqno;
50253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                u_char prefix[16], plen;
50353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tMH-Request ");
50453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 14) goto corrupt;
50553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                seqno = EXTRACT_16BITS(message + 4);
50653f17a9db278d33517d9888dd77848f554522a38JP Abgrall                rc = network_prefix(message[2], message[3], 0,
50753f17a9db278d33517d9888dd77848f554522a38JP Abgrall                                    message + 16, NULL, len - 14, prefix);
50853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(rc < 0) goto corrupt;
50953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                plen = message[3] + (message[2] == 1 ? 96 : 0);
51053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("(%u hops) for %s seqno %u id %s",
51153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       message[6], format_prefix(prefix, plen),
51253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       seqno, format_id(message + 8));
51353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
51453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
51553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
51653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_TSPC :
51753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
51853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" tspc");
51953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
52053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tTS/PC ");
52153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 6) goto corrupt;
52253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("timestamp %u packetcounter %u", EXTRACT_32BITS (message + 4),
52353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                       EXTRACT_16BITS(message + 2));
52453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
52553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
52653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case MESSAGE_HMAC : {
52753f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
52853f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" hmac");
52953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else {
53053f17a9db278d33517d9888dd77848f554522a38JP Abgrall                unsigned j;
53153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tHMAC ");
53253f17a9db278d33517d9888dd77848f554522a38JP Abgrall                if(len < 18) goto corrupt;
53353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("key-id %u digest-%u ", EXTRACT_16BITS(message + 2), len - 2);
53453f17a9db278d33517d9888dd77848f554522a38JP Abgrall                for (j = 0; j < len - 2; j++)
53553f17a9db278d33517d9888dd77848f554522a38JP Abgrall                    printf ("%02X", message[4 + j]);
53653f17a9db278d33517d9888dd77848f554522a38JP Abgrall            }
53753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
53853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
53953f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
54053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if(!vflag)
54153f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf(" unknown");
54253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            else
54353f17a9db278d33517d9888dd77848f554522a38JP Abgrall                printf("\n\tUnknown message type %d", type);
54453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
54553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        i += len + 2;
54653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
54753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
54853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
54953f17a9db278d33517d9888dd77848f554522a38JP Abgrall trunc:
55053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf(" [|babel]");
55153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
55253f17a9db278d33517d9888dd77848f554522a38JP Abgrall
55353f17a9db278d33517d9888dd77848f554522a38JP Abgrall corrupt:
55453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf(" (corrupt)");
55553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
55653f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
557