153f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Copyright (c) 1998-2006 The TCPDUMP project
353f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
453f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Redistribution and use in source and binary forms, with or without
553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * modification, are permitted provided that: (1) source code
653f17a9db278d33517d9888dd77848f554522a38JP Abgrall * distributions retain the above copyright notice and this paragraph
753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * in its entirety, and (2) distributions including binary code include
853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the above copyright notice and this paragraph in its entirety in
953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * the documentation or other materials provided with the distribution.
1053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
1153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
1253f17a9db278d33517d9888dd77848f554522a38JP Abgrall * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * FOR A PARTICULAR PURPOSE.
1453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
1553f17a9db278d33517d9888dd77848f554522a38JP Abgrall * support for the Cisco prop. VQP Protocol
1653f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
1753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * Original code by Carles Kishimoto <Carles.Kishimoto@bsc.es>
1853f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
1953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifndef lint
2153f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const char rcsid[] _U_ =
2253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    "@(#) $Header: /tcpdump/master/tcpdump/print-vqp.c,v 1.3 2006-08-19 06:51:13 guy Exp $";
2353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
2453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#ifdef HAVE_CONFIG_H
2653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "config.h"
2753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#endif
2853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
2953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <tcpdump-stdinc.h>
3053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <stdio.h>
3253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <stdlib.h>
3353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include <string.h>
3453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "interface.h"
3653f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "extract.h"
3753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#include "addrtoname.h"
3853f17a9db278d33517d9888dd77848f554522a38JP Abgrall
3953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_VERSION            		1
4053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_EXTRACT_VERSION(x) ((x)&0xFF)
4153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
4253f17a9db278d33517d9888dd77848f554522a38JP Abgrall/*
4353f17a9db278d33517d9888dd77848f554522a38JP Abgrall * VQP common header
4453f17a9db278d33517d9888dd77848f554522a38JP Abgrall *
4553f17a9db278d33517d9888dd77848f554522a38JP Abgrall *  0                   1                   2                   3
4653f17a9db278d33517d9888dd77848f554522a38JP Abgrall *  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
4753f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
4853f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |   Constant    | Packet type   |  Error Code   |    nitems     |
4953f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5053f17a9db278d33517d9888dd77848f554522a38JP Abgrall * |                Packet Sequence Number (4 bytes)               |
5153f17a9db278d33517d9888dd77848f554522a38JP Abgrall * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
5253f17a9db278d33517d9888dd77848f554522a38JP Abgrall */
5353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
5453f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct vqp_common_header_t {
5553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t version;
5653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t msg_type;
5753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t error_code;
5853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t nitems;
5953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t sequence[4];
6053f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
6153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstruct vqp_obj_tlv_t {
6353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t obj_type[4];
6453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t obj_length[2];
6553f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
6653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
6753f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_REQ_JOIN_PORT  0x01
6853f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_RESP_VLAN      0x02
6953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_REQ_RECONFIRM  0x03
7053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_RESP_RECONFIRM 0x04
7153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
7253f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok vqp_msg_type_values[] = {
7353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_REQ_JOIN_PORT, "Request, Join Port"},
7453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_RESP_VLAN, "Response, VLAN"},
7553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_REQ_RECONFIRM, "Request, Reconfirm"},
7653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_RESP_RECONFIRM, "Response, Reconfirm"},
7753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
7853f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
7953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
8053f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok vqp_error_code_values[] = {
8153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0x00, "No error"},
8253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0x03, "Access denied"},
8353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0x04, "Shutdown port"},
8453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0x05, "Wrong VTP domain"},
8553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
8653f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
8753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
8853f17a9db278d33517d9888dd77848f554522a38JP Abgrall/* FIXME the heading 0x0c looks ugly - those must be flags etc. */
8953f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_IP_ADDRESS    0x0c01
9053f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_PORT_NAME     0x0c02
9153f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_VLAN_NAME     0x0c03
9253f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_VTP_DOMAIN    0x0c04
9353f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_ETHERNET_PKT  0x0c05
9453f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_MAC_NULL      0x0c06
9553f17a9db278d33517d9888dd77848f554522a38JP Abgrall#define VQP_OBJ_MAC_ADDRESS   0x0c08
9653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
9753f17a9db278d33517d9888dd77848f554522a38JP Abgrallstatic const struct tok vqp_obj_values[] = {
9853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_IP_ADDRESS, "Client IP Address" },
9953f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_PORT_NAME, "Port Name" },
10053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_VLAN_NAME, "VLAN Name" },
10153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_VTP_DOMAIN, "VTP Domain" },
10253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_ETHERNET_PKT, "Ethernet Packet" },
10353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_MAC_NULL, "MAC Null" },
10453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { VQP_OBJ_MAC_ADDRESS, "MAC Address" },
10553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    { 0, NULL}
10653f17a9db278d33517d9888dd77848f554522a38JP Abgrall};
10753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
10853f17a9db278d33517d9888dd77848f554522a38JP Abgrallvoid
10953f17a9db278d33517d9888dd77848f554522a38JP Abgrallvqp_print(register const u_char *pptr, register u_int len)
11053f17a9db278d33517d9888dd77848f554522a38JP Abgrall{
11153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const struct vqp_common_header_t *vqp_common_header;
11253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const struct vqp_obj_tlv_t *vqp_obj_tlv;
11353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
11453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    const u_char *tptr;
11553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int16_t vqp_obj_len;
11653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int32_t vqp_obj_type;
11753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    int tlen;
11853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    u_int8_t nitems;
11953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
12053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tptr=pptr;
12153f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tlen = len;
12253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    vqp_common_header = (const struct vqp_common_header_t *)pptr;
12353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    TCHECK(*vqp_common_header);
12453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
12553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /*
12653f17a9db278d33517d9888dd77848f554522a38JP Abgrall     * Sanity checking of the header.
12753f17a9db278d33517d9888dd77848f554522a38JP Abgrall     */
12853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) {
12953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	printf("VQP version %u packet not supported",
13053f17a9db278d33517d9888dd77848f554522a38JP Abgrall               VQP_EXTRACT_VERSION(vqp_common_header->version));
13153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	return;
13253f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
13353f17a9db278d33517d9888dd77848f554522a38JP Abgrall
13453f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* in non-verbose mode just lets print the basic Message Type */
13553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    if (vflag < 1) {
13653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        printf("VQPv%u %s Message, error-code %s (%u), length %u",
13753f17a9db278d33517d9888dd77848f554522a38JP Abgrall               VQP_EXTRACT_VERSION(vqp_common_header->version),
13853f17a9db278d33517d9888dd77848f554522a38JP Abgrall               tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
13953f17a9db278d33517d9888dd77848f554522a38JP Abgrall               tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
14053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	       vqp_common_header->error_code,
14153f17a9db278d33517d9888dd77848f554522a38JP Abgrall               len);
14253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        return;
14353f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
14453f17a9db278d33517d9888dd77848f554522a38JP Abgrall
14553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* ok they seem to want to know everything - lets fully decode it */
14653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    nitems = vqp_common_header->nitems;
14753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u",
14853f17a9db278d33517d9888dd77848f554522a38JP Abgrall           VQP_EXTRACT_VERSION(vqp_common_header->version),
14953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	   tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
15053f17a9db278d33517d9888dd77848f554522a38JP Abgrall	   tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
15153f17a9db278d33517d9888dd77848f554522a38JP Abgrall	   vqp_common_header->error_code,
15253f17a9db278d33517d9888dd77848f554522a38JP Abgrall           EXTRACT_32BITS(&vqp_common_header->sequence),
15353f17a9db278d33517d9888dd77848f554522a38JP Abgrall           nitems,
15453f17a9db278d33517d9888dd77848f554522a38JP Abgrall           len);
15553f17a9db278d33517d9888dd77848f554522a38JP Abgrall
15653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    /* skip VQP Common header */
15753f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tptr+=sizeof(const struct vqp_common_header_t);
15853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    tlen-=sizeof(const struct vqp_common_header_t);
15953f17a9db278d33517d9888dd77848f554522a38JP Abgrall
16053f17a9db278d33517d9888dd77848f554522a38JP Abgrall    while (nitems > 0 && tlen > 0) {
16153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
16253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
16353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
16453f17a9db278d33517d9888dd77848f554522a38JP Abgrall        vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
16553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tptr+=sizeof(struct vqp_obj_tlv_t);
16653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        tlen-=sizeof(struct vqp_obj_tlv_t);
16753f17a9db278d33517d9888dd77848f554522a38JP Abgrall
16853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        printf("\n\t  %s Object (0x%08x), length %u, value: ",
16953f17a9db278d33517d9888dd77848f554522a38JP Abgrall               tok2str(vqp_obj_values, "Unknown", vqp_obj_type),
17053f17a9db278d33517d9888dd77848f554522a38JP Abgrall               vqp_obj_type, vqp_obj_len);
17153f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17253f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /* basic sanity check */
17353f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if (vqp_obj_type == 0 || vqp_obj_len ==0) {
17453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            return;
17553f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
17653f17a9db278d33517d9888dd77848f554522a38JP Abgrall
17753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        /* did we capture enough for fully decoding the object ? */
17853f17a9db278d33517d9888dd77848f554522a38JP Abgrall        if (!TTEST2(*tptr, vqp_obj_len))
17953f17a9db278d33517d9888dd77848f554522a38JP Abgrall            goto trunc;
18053f17a9db278d33517d9888dd77848f554522a38JP Abgrall
18153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        switch(vqp_obj_type) {
18253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case VQP_OBJ_IP_ADDRESS:
18353f17a9db278d33517d9888dd77848f554522a38JP Abgrall            printf("%s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr));
18453f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
18553f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /* those objects have similar semantics - fall through */
18653f17a9db278d33517d9888dd77848f554522a38JP Abgrall        case VQP_OBJ_PORT_NAME:
18753f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case VQP_OBJ_VLAN_NAME:
18853f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case VQP_OBJ_VTP_DOMAIN:
18953f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case VQP_OBJ_ETHERNET_PKT:
19053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            safeputs((const char *)tptr, vqp_obj_len);
19153f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
19253f17a9db278d33517d9888dd77848f554522a38JP Abgrall            /* those objects have similar semantics - fall through */
19353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case VQP_OBJ_MAC_ADDRESS:
19453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	case VQP_OBJ_MAC_NULL:
19553f17a9db278d33517d9888dd77848f554522a38JP Abgrall	      printf("%s", etheraddr_string(tptr));
19653f17a9db278d33517d9888dd77848f554522a38JP Abgrall              break;
19753f17a9db278d33517d9888dd77848f554522a38JP Abgrall        default:
19853f17a9db278d33517d9888dd77848f554522a38JP Abgrall            if (vflag <= 1)
19953f17a9db278d33517d9888dd77848f554522a38JP Abgrall                print_unknown_data(tptr, "\n\t    ", vqp_obj_len);
20053f17a9db278d33517d9888dd77848f554522a38JP Abgrall            break;
20153f17a9db278d33517d9888dd77848f554522a38JP Abgrall        }
20253f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tptr += vqp_obj_len;
20353f17a9db278d33517d9888dd77848f554522a38JP Abgrall	tlen -= vqp_obj_len;
20453f17a9db278d33517d9888dd77848f554522a38JP Abgrall	nitems--;
20553f17a9db278d33517d9888dd77848f554522a38JP Abgrall    }
20653f17a9db278d33517d9888dd77848f554522a38JP Abgrall    return;
20753f17a9db278d33517d9888dd77848f554522a38JP Abgralltrunc:
20853f17a9db278d33517d9888dd77848f554522a38JP Abgrall    printf("\n\t[|VQP]");
20953f17a9db278d33517d9888dd77848f554522a38JP Abgrall}
210