/*
 * Copyright (c) 1998-2006 The TCPDUMP project
 *
 * 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, and (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.
 * 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.
 *
 * support for the Cisco prop. VQP Protocol 
 *
 * Original code by Carles Kishimoto <Carles.Kishimoto@bsc.es>
 */

#ifndef lint
static const char rcsid[] _U_ =
    "@(#) $Header: /tcpdump/master/tcpdump/print-vqp.c,v 1.3 2006-08-19 06:51:13 guy Exp $";
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <tcpdump-stdinc.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "interface.h"
#include "extract.h"
#include "addrtoname.h"

#define VQP_VERSION            		1
#define VQP_EXTRACT_VERSION(x) ((x)&0xFF)

/*
 * VQP common header
 *
 *  0                   1                   2                   3
 *  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
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |   Constant    | Packet type   |  Error Code   |    nitems     |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 * |                Packet Sequence Number (4 bytes)               |
 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 */

struct vqp_common_header_t {
    u_int8_t version;
    u_int8_t msg_type;
    u_int8_t error_code;
    u_int8_t nitems;
    u_int8_t sequence[4];
};

struct vqp_obj_tlv_t {
    u_int8_t obj_type[4];
    u_int8_t obj_length[2];
};

#define VQP_OBJ_REQ_JOIN_PORT  0x01
#define VQP_OBJ_RESP_VLAN      0x02
#define VQP_OBJ_REQ_RECONFIRM  0x03
#define VQP_OBJ_RESP_RECONFIRM 0x04

static const struct tok vqp_msg_type_values[] = {
    { VQP_OBJ_REQ_JOIN_PORT, "Request, Join Port"},
    { VQP_OBJ_RESP_VLAN, "Response, VLAN"},
    { VQP_OBJ_REQ_RECONFIRM, "Request, Reconfirm"},
    { VQP_OBJ_RESP_RECONFIRM, "Response, Reconfirm"},
    { 0, NULL}
};

static const struct tok vqp_error_code_values[] = {
    { 0x00, "No error"},
    { 0x03, "Access denied"},
    { 0x04, "Shutdown port"},
    { 0x05, "Wrong VTP domain"},
    { 0, NULL}
};

/* FIXME the heading 0x0c looks ugly - those must be flags etc. */
#define VQP_OBJ_IP_ADDRESS    0x0c01
#define VQP_OBJ_PORT_NAME     0x0c02
#define VQP_OBJ_VLAN_NAME     0x0c03
#define VQP_OBJ_VTP_DOMAIN    0x0c04
#define VQP_OBJ_ETHERNET_PKT  0x0c05
#define VQP_OBJ_MAC_NULL      0x0c06
#define VQP_OBJ_MAC_ADDRESS   0x0c08

static const struct tok vqp_obj_values[] = {
    { VQP_OBJ_IP_ADDRESS, "Client IP Address" },
    { VQP_OBJ_PORT_NAME, "Port Name" },
    { VQP_OBJ_VLAN_NAME, "VLAN Name" },
    { VQP_OBJ_VTP_DOMAIN, "VTP Domain" },
    { VQP_OBJ_ETHERNET_PKT, "Ethernet Packet" },
    { VQP_OBJ_MAC_NULL, "MAC Null" },
    { VQP_OBJ_MAC_ADDRESS, "MAC Address" },
    { 0, NULL}
};

void
vqp_print(register const u_char *pptr, register u_int len) 
{
    const struct vqp_common_header_t *vqp_common_header;
    const struct vqp_obj_tlv_t *vqp_obj_tlv;

    const u_char *tptr;
    u_int16_t vqp_obj_len;
    u_int32_t vqp_obj_type;
    int tlen;
    u_int8_t nitems;

    tptr=pptr;
    tlen = len;
    vqp_common_header = (const struct vqp_common_header_t *)pptr;
    TCHECK(*vqp_common_header);

    /*
     * Sanity checking of the header.
     */
    if (VQP_EXTRACT_VERSION(vqp_common_header->version) != VQP_VERSION) {
	printf("VQP version %u packet not supported",
               VQP_EXTRACT_VERSION(vqp_common_header->version));
	return;
    }

    /* in non-verbose mode just lets print the basic Message Type */
    if (vflag < 1) {
        printf("VQPv%u %s Message, error-code %s (%u), length %u",
               VQP_EXTRACT_VERSION(vqp_common_header->version),
               tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
               tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
	       vqp_common_header->error_code,
               len);
        return;
    }
    
    /* ok they seem to want to know everything - lets fully decode it */
    nitems = vqp_common_header->nitems;
    printf("\n\tVQPv%u, %s Message, error-code %s (%u), seq 0x%08x, items %u, length %u",
           VQP_EXTRACT_VERSION(vqp_common_header->version),
	   tok2str(vqp_msg_type_values, "unknown (%u)",vqp_common_header->msg_type),
	   tok2str(vqp_error_code_values, "unknown (%u)",vqp_common_header->error_code),
	   vqp_common_header->error_code,
           EXTRACT_32BITS(&vqp_common_header->sequence),
           nitems,
           len);

    /* skip VQP Common header */
    tptr+=sizeof(const struct vqp_common_header_t);
    tlen-=sizeof(const struct vqp_common_header_t);

    while (nitems > 0 && tlen > 0) {

        vqp_obj_tlv = (const struct vqp_obj_tlv_t *)tptr;
        vqp_obj_type = EXTRACT_32BITS(vqp_obj_tlv->obj_type);
        vqp_obj_len = EXTRACT_16BITS(vqp_obj_tlv->obj_length);
        tptr+=sizeof(struct vqp_obj_tlv_t);
        tlen-=sizeof(struct vqp_obj_tlv_t);

        printf("\n\t  %s Object (0x%08x), length %u, value: ",
               tok2str(vqp_obj_values, "Unknown", vqp_obj_type),
               vqp_obj_type, vqp_obj_len);

        /* basic sanity check */
        if (vqp_obj_type == 0 || vqp_obj_len ==0) {
            return;
        }

        /* did we capture enough for fully decoding the object ? */
        if (!TTEST2(*tptr, vqp_obj_len)) 
            goto trunc;

        switch(vqp_obj_type) {
	case VQP_OBJ_IP_ADDRESS:
            printf("%s (0x%08x)", ipaddr_string(tptr), EXTRACT_32BITS(tptr));
            break;
            /* those objects have similar semantics - fall through */
        case VQP_OBJ_PORT_NAME:
	case VQP_OBJ_VLAN_NAME:
	case VQP_OBJ_VTP_DOMAIN:
	case VQP_OBJ_ETHERNET_PKT:
            safeputs((const char *)tptr, vqp_obj_len);
            break;
            /* those objects have similar semantics - fall through */
	case VQP_OBJ_MAC_ADDRESS:
	case VQP_OBJ_MAC_NULL:
	      printf("%s", etheraddr_string(tptr));
              break;
        default:
            if (vflag <= 1)
                print_unknown_data(tptr, "\n\t    ", vqp_obj_len);
            break;
        }
	tptr += vqp_obj_len;
	tlen -= vqp_obj_len;
	nitems--;
    }
    return;
trunc:
    printf("\n\t[|VQP]");
}
