/**************************************************************************** ** 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); }