/****************************************************************************
** File: ipv6.c
**
** Author: Mike Borella
**
** Comments: Dump IP header information
**
** $Id: ipv6.c,v 1.14 2002/01/03 00:04:01 mborella 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 "ipv6.h"
#include "ip_protocols.h"
#define HOLDER_SIZE 64
/* Structure of IPv6 header */
typedef struct ipv6_header
{
#if defined(WORDS_BIGENDIAN)
u_int8_t version:4,
traffic_class_high:4;
u_int8_t traffic_class_low:4,
flow_label_high:4;
#else
u_int8_t traffic_class_high:4,
version:4;
u_int8_t flow_label_high:4,
traffic_class_low:4;
#endif
u_int16_t flow_label_low;
u_int16_t payload_length;
u_int8_t next_header;
u_int8_t hop_limit;
u_int8_t src_addr[16];
u_int8_t dst_addr[16];
} ipv6_header_t;
extern struct arg_t *my_args;
extern void (*ip_proto_func[])(packet_t *);
extern strmap_t ipproto_map[];
/*----------------------------------------------------------------------------
**
** dump_ipv6()
**
** Parse IPv6 header and dump fields
**
**----------------------------------------------------------------------------
*/
void dump_ipv6(packet_t *pkt)
{
ipv6_header_t ipv6;
char holder[HOLDER_SIZE];
u_int8_t ver;
u_int8_t class;
u_int32_t flow;
/* Set the layer */
set_layer(LAYER_NETWORK);
/*
* Stats accounting
*/
stats_update(STATS_IPV6);
/*
* Stats accounting
*/
stats_update(STATS_IP);
/*
* Get the IPv6 header
*/
if (get_packet_bytes((u_int8_t *) &ipv6, pkt, 40) == 0)
return;
/*
* Conversions
*/
ver = ipv6.version;
class = ipv6.traffic_class_high * 16 + ipv6.traffic_class_low;
flow = ipv6.flow_label_high * 65536 + ntohs(ipv6.flow_label_low);
ipv6.payload_length = ntohs(ipv6.payload_length);
/*
* Dump header
*/
if (my_args->m)
{
display_minimal_string("| IPv6 ");
display_minimal_ipv6((u_int8_t *) &ipv6.src_addr);
display_minimal_string("->");
display_minimal_ipv6((u_int8_t *) &ipv6.dst_addr);
display_minimal_string(" ");
}
else
{
/* announcement */
display_header_banner("IPv6 Header");
/* print fields */
display("Version", (u_int8_t *) &ver, 1, DISP_DEC);
display("Traffic class", (u_int8_t *) &class, 1, DISP_HEX);
display("Flow label", (u_int8_t *) &flow, 4, DISP_HEX);
display("Payload length", (u_int8_t *) &ipv6.payload_length, 2,
DISP_DEC);
snprintf(holder, HOLDER_SIZE, "%d (%s)", ipv6.next_header,
map2str(ipproto_map, ipv6.next_header));
display("Next header", holder, strlen(holder), DISP_STRING);
display("Hop limit", (u_int8_t *) &ipv6.hop_limit, 1, DISP_DEC);
display_ipv6("Source address",(u_int8_t *) &ipv6.src_addr);
display_ipv6("Destination address",(u_int8_t *) &ipv6.dst_addr);
}
/* dump the hex buffer */
hexbuffer_flush();
/*
* Hand it to the next higher level protocol.
*/
if (ip_proto_func[ipv6.next_header])
ip_proto_func[ipv6.next_header](pkt);
}
syntax highlighted by Code2HTML, v. 0.9.1