/**************************************************************************** 
** File: ipx.c
**
** Author: Mike Borella
**
** Dump IPX header information
**
** $Id: ipx.c,v 1.14 2007/06/25 12:06:34 farooq-i-azam Exp $
**
** This program is free software; you can redistribute it and/or modify
** it under the terms of the GNU General Public License as published by
** the Free Software Foundation; either version 2 of the License, or
** (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
** GNU Library General Public License for more details.
**
** You should have received a copy of the GNU General Public License
** along with this program; if not, write to the Free Software
** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
**
*****************************************************************************/

#include "ipx.h"
#include "spx.h"
#include "ipxrip.h"

#define HOLDER_SIZE 64

/*
 * IPX packet type map
 */

strmap_t ipx_packettype_map[] =
{
  { IPX_PACKETTYPE_UNKNOWN,        "unknown" },
  { IPX_PACKETTYPE_RIP,            "RIP" },
  { IPX_PACKETTYPE_ECHO,           "echo" },
  { IPX_PACKETTYPE_ERROR,          "error" },
  { IPX_PACKETTYPE_PEP,            "PEP" },
  { IPX_PACKETTYPE_SPX,            "SPX" },
  { IPX_PACKETTYPE_NCP,            "NCP" },
  { IPX_PACKETTYPE_NETBIOS,        "NetBIOS" },
  { 0, "" }
};

extern struct arg_t *my_args;

/*----------------------------------------------------------------------------
**
** dump_ipx()
**
** Parse IPX header and dump fields
**
**----------------------------------------------------------------------------
*/

void dump_ipx(packet_t *pkt)
{
  ipx_header_t ipx;
  char holder[HOLDER_SIZE];
 
  /* Set the layer */
  set_layer(LAYER_NETWORK);

  /*
   * Stats accounting
   */

  stats_update(STATS_IPX);

  /*
   * Get the IPX header
   */

  if (get_packet_bytes((u_int8_t *) &ipx, pkt, 30) == 0)
    return;

  /*
   * Conversions
   */

  ipx.csum = ntohs(ipx.csum);
  ipx.len = ntohs(ipx.len);
  ipx.dstnet = ntohl(ipx.dstnet);
  ipx.dstport = ntohs(ipx.dstport);
  ipx.srcnet = ntohl(ipx.srcnet);
  ipx.srcport = ntohs(ipx.srcport);

  /*
   * Dump header
   */
  
  if (my_args->m && !my_args->n)
    {
      display_minimal_string("| IPX ");    
      display_minimal((u_int8_t *) &ipx.srcnode, 6, DISP_HEXCOLONS);
      display_minimal_string("->");
      display_minimal((u_int8_t *) &ipx.dstnode, 6, DISP_HEXCOLONS);
      display_minimal_string(" ");      
    }
  else 
    {
      /* announcement */
      display_header_banner("IPX Header");
      
      /* Checksum, length, transport */
      display("Checksum", (u_int8_t *) &ipx.csum, 2, DISP_DEC);
      display("Packet length", (u_int8_t *) &ipx.len, 2, DISP_DEC);
      display("Transport control", (u_int8_t *) &ipx.tc, 1, DISP_DEC);
      
      /* packet type */
      snprintf(holder, HOLDER_SIZE, "%d (%s)", ipx.pt, 
	       map2str(ipx_packettype_map, ipx.pt));
      display("Packet type", (u_int8_t *) holder, strlen(holder), 
	      DISP_STRING);
      
      /* destination network information */
      display("Destination network", (u_int8_t *) &ipx.dstnet, 4, 
	      DISP_DEC);
      display("Destination node", (u_int8_t *) &ipx.dstnode, 6, 
	      DISP_HEXCOLONS);
      display("Destination port", (u_int8_t *) &ipx.dstport, 2, 
	      DISP_DEC);
      
      /* source network information */
      display("Source network", (u_int8_t *) &ipx.srcnet, 4, 
	      DISP_DEC);
      display("Source node", (u_int8_t *) &ipx.srcnode, 6, 
	      DISP_HEXCOLONS);
      display("Source port", (u_int8_t *) &ipx.srcport, 2, DISP_DEC);
    }
  
  /* dump the hex buffer */
  hexbuffer_flush();

  /*
   * Hand it to the next higher layer protocol.
   */
  
  switch (ipx.pt) 
    {
    case 1: 
      dump_ipxrip(pkt);
      break;
      
    case 5:
      dump_spx(pkt);
      break; 
      
    default:
      break;
    }
  
}
