/**************************************************************************** ** ** File: isakmp.c ** ** Extensions and additions by: Stuart Stock (stuart@ins.com) ** Original Author: Mike Borella ** ** Comments: Dump ISAKMP headers under IPSec DOI ** ** See RFC 2408 "Internet Security Association and Key Management Protocol" ** and RFC 2407 "The Internet IP Security Domain Interpretation for ISAKMP" ** ** and when you can't find the value anywhere else, look in: ** draft-ietf-ipsec-ike-01 "The Internet Key Exchange (IKE)" ** ** $Id: isakmp.c,v 1.10 2001/05/28 19:24:04 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 "isakmp.h" #include "payload.h" extern strmap_t ipproto_map[]; extern struct arg_t * my_args; #define ISAKMP_DOI_IPSEC 1 /* * Static part of ISAKMP header */ typedef struct isakmp { char i_cookie[8]; char r_cookie[8]; #if defined(WORDS_BIGENDIAN) u_int16_t maj_version:4, min_version:4, next_payload:8; #else u_int16_t next_payload:8, min_version:4, maj_version:4; #endif u_int8_t exchange_type; u_int8_t flags; u_int32_t msg_id; u_int32_t length; } isakmp_t; /* * ISAKMP Generic Payload Header */ typedef struct isakmpgeneric { u_int8_t next_payload; u_int8_t reserved; u_int16_t length; } isakmpgeneric_t; /* * ISAKMP proposal payload (partial) */ typedef struct isakmpproposal { u_int8_t number; u_int8_t protocol_id; u_int8_t spi_size; u_int8_t num_transforms; } isakmpproposal_t; /* * ISAKMP transform payload (partial) */ typedef struct isakmptransform { u_int8_t number; u_int8_t id; u_int16_t reserved; } isakmptransform_t; /* * ISAKMP flags */ #define ISAKMP_FLAG_ENCRYPTION 0x01 #define ISAKMP_FLAG_COMMIT 0x02 #define ISAKMP_FLAG_AUTHONLY 0x04 /* * ISAKMP payload types */ #define ISAKMP_PAYLOAD_NONE 0 #define ISAKMP_PAYLOAD_SA 1 #define ISAKMP_PAYLOAD_PROPOSAL 2 #define ISAKMP_PAYLOAD_TRANSFORM 3 #define ISAKMP_PAYLOAD_KEYEXCHANGE 4 #define ISAKMP_PAYLOAD_IDENTIFICATION 5 #define ISAKMP_PAYLOAD_CERTIFICATE 6 #define ISAKMP_PAYLOAD_CERTIFICATEREQ 7 #define ISAKMP_PAYLOAD_HASH 8 #define ISAKMP_PAYLOAD_SIGNATURE 9 #define ISAKMP_PAYLOAD_NONCE 10 #define ISAKMP_PAYLOAD_NOTIFICATION 11 #define ISAKMP_PAYLOAD_DELETE 12 #define ISAKMP_PAYLOAD_VENDORID 13 /* * ISAKMP payload map */ strmap_t isakmp_payload_map[] = { { ISAKMP_PAYLOAD_NONE, "none" }, { ISAKMP_PAYLOAD_SA, "security association" }, { ISAKMP_PAYLOAD_PROPOSAL, "proposal" }, { ISAKMP_PAYLOAD_TRANSFORM, "transform" }, { ISAKMP_PAYLOAD_KEYEXCHANGE, "key exchange" }, { ISAKMP_PAYLOAD_IDENTIFICATION, "identification" }, { ISAKMP_PAYLOAD_CERTIFICATE, "certificate" }, { ISAKMP_PAYLOAD_CERTIFICATEREQ, "certificate request" }, { ISAKMP_PAYLOAD_HASH, "hash" }, { ISAKMP_PAYLOAD_SIGNATURE, "signature" }, { ISAKMP_PAYLOAD_NONCE, "nonce" }, { ISAKMP_PAYLOAD_NOTIFICATION, "notification" }, { ISAKMP_PAYLOAD_DELETE, "delete" }, { ISAKMP_PAYLOAD_VENDORID, "vendor id" }, { 0, "" } }; /* * ISAKMP exchange types */ #define ISAKMP_EXCHANGE_NONE 0 #define ISAKMP_EXCHANGE_BASE 1 #define ISAKMP_EXCHANGE_IDPROTECT 2 #define ISAKMP_EXCHANGE_AUTHONLY 3 #define ISAKMP_EXCHANGE_AGGRESSIVE 4 #define ISAKMP_EXCHANGE_INFORMATIONAL 5 /* * ISAKMP exchange map */ strmap_t isakmp_exchange_map[] = { { ISAKMP_EXCHANGE_NONE, "none" }, { ISAKMP_EXCHANGE_BASE, "base" }, { ISAKMP_EXCHANGE_IDPROTECT, "identity protection" }, { ISAKMP_EXCHANGE_AUTHONLY, "authentication only" }, { ISAKMP_EXCHANGE_AGGRESSIVE, "aggressive" }, { ISAKMP_EXCHANGE_INFORMATIONAL, "informational" }, { 0, "" } }; /* * Situation definitions for IPSEC DOI */ #define ISAKMP_SIT_IDENTITYONLY 0x01 #define ISAKMP_SIT_SECRECY 0x02 #define ISAKMP_SIT_INTEGRITY 0x04 /* * IPSEC DOI situation map */ strmap_t isakmp_doisituation_map[] = { { ISAKMP_SIT_IDENTITYONLY, "identity only" }, { ISAKMP_SIT_SECRECY, "secrecy" }, { ISAKMP_SIT_INTEGRITY, "integrity" }, { 0, "" } }; /* * Protocol ID definitions */ #define ISAKMP_PROTOCOLID_RESERVED 0 #define ISAKMP_PROTOCOLID_ISAKMP 1 #define ISAKMP_PROTOCOLID_IPSECAH 2 #define ISAKMP_PROTOCOLID_IPSECESP 3 #define ISAKMP_PROTOCOLID_IPCOMP 4 /* * Protocol ID map */ strmap_t isakmp_protocolid_map[] = { { ISAKMP_PROTOCOLID_RESERVED, "reserved" }, { ISAKMP_PROTOCOLID_ISAKMP, "ISAKMP" }, { ISAKMP_PROTOCOLID_IPSECAH, "IPSEC AH" }, { ISAKMP_PROTOCOLID_IPSECESP, "IPSEC ESP" }, { ISAKMP_PROTOCOLID_IPCOMP, "IPCOMP" }, { 0, "" } }; /* * Transform definitions */ #define ISAKMP_TRANSFORM_RESERVED 0 #define ISAKMP_TRANSFORM_KEYIKE 1 /* * Transform map */ strmap_t isakmp_transform_map[] = { { ISAKMP_TRANSFORM_RESERVED, "reserved" }, { ISAKMP_TRANSFORM_KEYIKE, "KEY_IKE" }, { 0, "" } }; /* * Attribute types */ #define ISAKMP_ATTR_ENCRALG 1 #define ISAKMP_ATTR_HASHALG 2 #define ISAKMP_ATTR_AUTHMETHOD 3 #define ISAKMP_ATTR_GROUPDESC 4 #define ISAKMP_ATTR_GROUPTYPE 5 #define ISAKMP_ATTR_GROUPPRIME 6 #define ISAKMP_ATTR_GROUPGEN1 7 #define ISAKMP_ATTR_GROUPGEN2 8 #define ISAKMP_ATTR_GROUPCURVEA 9 #define ISAKMP_ATTR_GROUPCURVEB 10 #define ISAKMP_ATTR_LIFETYPE 11 #define ISAKMP_ATTR_LIFEDURATION 12 #define ISAKMP_ATTR_PRF 13 #define ISAKMP_ATTR_KEYLENGTH 14 #define ISAKMP_ATTR_FIELDSIZE 15 #define ISAKMP_ATTR_GROUPORDER 16 /* * Attribute type map */ strmap_t isakmp_attr_map[] = { { ISAKMP_ATTR_ENCRALG, "encryption algorithm" }, { ISAKMP_ATTR_HASHALG, "hash algorithm" }, { ISAKMP_ATTR_AUTHMETHOD, "authentication method" }, { ISAKMP_ATTR_GROUPDESC, "group description" }, { ISAKMP_ATTR_GROUPTYPE, "group type" }, { ISAKMP_ATTR_GROUPPRIME, "group prime" }, { ISAKMP_ATTR_GROUPGEN1, "group generator 1" }, { ISAKMP_ATTR_GROUPGEN2, "group generator 2" }, { ISAKMP_ATTR_GROUPCURVEA, "group curve A" }, { ISAKMP_ATTR_GROUPCURVEB, "group curve B" }, { ISAKMP_ATTR_LIFETYPE, "life type" }, { ISAKMP_ATTR_LIFEDURATION, "life duration" }, { ISAKMP_ATTR_PRF, "PRF" }, { ISAKMP_ATTR_KEYLENGTH, "key length" }, { ISAKMP_ATTR_FIELDSIZE, "field size" }, { ISAKMP_ATTR_GROUPORDER, "group order" }, { 0, "" } }; /* * Encryption algorithm attribute types */ #define ISAKMP_ATTR_ENCRALG_DESCBC 1 #define ISAKMP_ATTR_ENCRALG_IDEACBC 2 #define ISAKMP_ATTR_ENCRALG_BLOWFISHCBC 3 #define ISAKMP_ATTR_ENCRALG_RC5R16B64CBC 4 #define ISAKMP_ATTR_ENCRALG_3DESCBC 5 #define ISAKMP_ATTR_ENCRALG_CASTCBC 6 /* * Encryption algorithm attribute map */ strmap_t isakmp_attr_encralg_map[] = { { ISAKMP_ATTR_ENCRALG_DESCBC, "DES-CBC" }, { ISAKMP_ATTR_ENCRALG_IDEACBC, "IDEA-CBC" }, { ISAKMP_ATTR_ENCRALG_BLOWFISHCBC, "blowfish-CBC" }, { ISAKMP_ATTR_ENCRALG_RC5R16B64CBC, "RC5-R16-B64-CBC" }, { ISAKMP_ATTR_ENCRALG_3DESCBC, "3DES-CBC" }, { ISAKMP_ATTR_ENCRALG_CASTCBC, "CAST-CBC" }, { 0, "" } }; /* * Hash algorithm attribute types */ #define ISAKMP_ATTR_HASHALG_MD5 1 #define ISAKMP_ATTR_HASHALG_SHA 2 #define ISAKMP_ATTR_HASHALG_TIGER 3 /* * Hash algorithm attribute map */ strmap_t isakmp_attr_hashalg_map[] = { { ISAKMP_ATTR_HASHALG_MD5, "MD5" }, { ISAKMP_ATTR_HASHALG_SHA, "SHA" }, { ISAKMP_ATTR_HASHALG_TIGER, "Tiger" }, { 0, "" } }; /* * Authentication method attribute types */ #define ISAKMP_ATTR_AUTHMETHOD_PRESHAREDKEY 1 #define ISAKMP_ATTR_AUTHMETHOD_DSSSIG 2 #define ISAKMP_ATTR_AUTHMETHOD_RSASIG 3 #define ISAKMP_ATTR_AUTHMETHOD_ENCRRSA 4 #define ISAKMP_ATTR_AUTHMETHOD_REVENCRRSA 5 /* * Authentication method attribute map */ strmap_t isakmp_attr_authmethod_map[] = { { ISAKMP_ATTR_AUTHMETHOD_PRESHAREDKEY, "pre-shared key" }, { ISAKMP_ATTR_AUTHMETHOD_DSSSIG, "DSS signatures" }, { ISAKMP_ATTR_AUTHMETHOD_RSASIG, "RSA signatures" }, { ISAKMP_ATTR_AUTHMETHOD_ENCRRSA, "encryption with RSA" }, { ISAKMP_ATTR_AUTHMETHOD_REVENCRRSA, "revised encryption with RSA" }, { 0, "" } }; /* * Group description attribute types */ #define ISAKMP_ATTR_GROUPDESC_MODP768 1 #define ISAKMP_ATTR_GROUPDESC_MODP1024 2 #define ISAKMP_ATTR_GROUPDESC_EC2N155 3 #define ISAKMP_ATTR_GROUPDESC_EC2N185 4 /* * Group description attribute map */ strmap_t isakmp_attr_groupdesc_map[] = { { ISAKMP_ATTR_GROUPDESC_MODP768, "768-bit MODP group" }, { ISAKMP_ATTR_GROUPDESC_MODP1024, "1024-bit MODP group" }, { ISAKMP_ATTR_GROUPDESC_EC2N155, "EC2N group on GP[2^155]" }, { ISAKMP_ATTR_GROUPDESC_EC2N185, "EC2N group on GP[2^185]" }, { 0, "" } }; /* * Group type attribute types */ #define ISAKMP_ATTR_GROUPTYPE_MODP 1 #define ISAKMP_ATTR_GROUPTYPE_ECP 2 #define ISAKMP_ATTR_GROUPTYPE_EC2N 3 /* * Group type attribute map */ strmap_t isakmp_attr_grouptype_map[] = { { ISAKMP_ATTR_GROUPTYPE_MODP, "modular exponentiation" }, { ISAKMP_ATTR_GROUPTYPE_ECP, "elliptical curve over GF[P]" }, { ISAKMP_ATTR_GROUPTYPE_EC2N, "elliptical curve over GF[2^N]" }, { 0, "" } }; /* * Life type attribute types */ #define ISAKMP_ATTR_LIFETYPE_SECONDS 1 #define ISAKMP_ATTR_LIFETYPE_KILOBYTES 2 /* * Life type attribute map */ strmap_t isakmp_attr_lifetype_map[] = { { ISAKMP_ATTR_LIFETYPE_SECONDS, "seconds" }, { ISAKMP_ATTR_LIFETYPE_KILOBYTES, "kilobytes" }, { 0, "" } }; void isakmp_next_payload(packet_t *, u_int8_t); /*---------------------------------------------------------------------------- ** ** dump_isakmp_attributes() ** ** Parse an ISAKMP attribute set and interpret it. This is for IKE with ** the IPSEC DOI only! ** **---------------------------------------------------------------------------- */ void dump_isakmp_attributes(u_int8_t *attr, int len) { u_int8_t * p; u_int16_t type; u_int16_t length; u_int8_t * value; p = attr; while (1) { /* get the type */ if (p+2 > attr+len) return; memcpy((void *) &type, (void * ) p, 2); type = ntohs(type); p = p + 2; if (type >= 0x8000) { u_int16_t temp; temp = type - 0x8000; display_strmap("Attribute", temp, isakmp_attr_map); } else display_strmap("Attribute", type, isakmp_attr_map); /* determine whether we have a length field or not */ if (type < 0x8000) { /* get length field */ if (p+2 > attr+len) return; memcpy((void *) &length, (void *) p, 2); length = ntohs(length); p = p + 2; display(" Length", (u_int8_t *) &length, 2, DISP_DEC); } else length = 2; /* * Get the value. Values without a length field should be 2 bytes. * It must say that in some RFC but I just can't find it... */ if (p+length > attr+len) return; value = my_malloc(length); memcpy((void *) value, (void *) p, length); reverse_byte_order(value, length); p = p + length; /* display the value, based on its type */ switch(type & 0x7fff) { case ISAKMP_ATTR_ENCRALG: display_strmap(" Value", (u_int16_t) *value, isakmp_attr_encralg_map); break; case ISAKMP_ATTR_HASHALG: display_strmap(" Value", (u_int16_t) *value, isakmp_attr_hashalg_map); break; case ISAKMP_ATTR_AUTHMETHOD: display_strmap(" Value", (u_int16_t) *value, isakmp_attr_authmethod_map); break; case ISAKMP_ATTR_GROUPDESC: display_strmap(" Value", (u_int16_t) *value, isakmp_attr_groupdesc_map); break; case ISAKMP_ATTR_GROUPTYPE: display_strmap(" Value", (u_int16_t) *value, isakmp_attr_grouptype_map); break; case ISAKMP_ATTR_LIFETYPE: display_strmap(" Value", (u_int16_t) *value, isakmp_attr_lifetype_map); break; default: display(" Value", (u_int8_t *) value, length, DISP_DEC); break; } my_free(value); } } /*---------------------------------------------------------------------------- ** ** dump_isakmp_transform() ** ** Parse ISAKMP transform payload ** **---------------------------------------------------------------------------- */ void dump_isakmp_transform(packet_t * pkt) { isakmpgeneric_t hdr; isakmptransform_t transform; u_int8_t * sa_attributes = NULL; int sa_attributes_len; /* get the generic header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0) return; /* conversions */ hdr.length = ntohs(hdr.length); if (my_args->m) { /* nothing to do here... */ } else { display_header_banner("ISAKMP/IKE transform"); display_strmap("Next payload", hdr.next_payload, isakmp_payload_map); display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC); display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC); } /* Get the fixed transform payload, then the SA attributes field */ if (get_packet_bytes((u_int8_t *) &transform, pkt, sizeof(isakmptransform_t)) == 0) return; sa_attributes_len = hdr.length - 8; if (sa_attributes_len > 0) { sa_attributes = (u_int8_t *) my_malloc(sa_attributes_len); if (get_packet_bytes(sa_attributes, pkt, sa_attributes_len) == 0) { my_free(sa_attributes); return; } } /* conversion */ transform.reserved = ntohs(transform.reserved); if (my_args->m) { /* nothing to do here... */ } else { display("Transform #", (u_int8_t *) &transform.number, 1, DISP_DEC); display_strmap("Transform ID", transform.id, isakmp_transform_map); display("Reserved", (u_int8_t *) &transform.reserved, 2, DISP_DEC); if (sa_attributes_len > 0) dump_isakmp_attributes(sa_attributes, sa_attributes_len); } /* Dump the hex buffer */ hexbuffer_flush(); /* free the sa_attrinutes memory */ if (sa_attributes_len > 0) my_free(sa_attributes); } /*---------------------------------------------------------------------------- ** ** dump_isakmp_proposal() ** ** Parse ISAKMP proposal payload ** **---------------------------------------------------------------------------- */ void dump_isakmp_proposal(packet_t * pkt) { isakmpgeneric_t hdr; isakmpproposal_t proposal; u_int8_t * spi = NULL; int i; /* get the generic header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0) return; /* conversions */ hdr.length = ntohs(hdr.length); if (my_args->m) { /* nothing to do here... */ } else { display_header_banner("ISAKMP/IKE proposal"); display_strmap("Next payload", hdr.next_payload, isakmp_payload_map); display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC); display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC); } /* get the proposal, then the SPI */ if (get_packet_bytes((u_int8_t *) &proposal, pkt, sizeof(proposal)) == 0) return; if (proposal.spi_size > 0) { spi = my_malloc(proposal.spi_size); if (get_packet_bytes((u_int8_t *) &spi, pkt, proposal.spi_size) == 0) { my_free(spi); return; } } if (my_args->m) { /* nothing to do here... */ } else { display("Proposal #", (u_int8_t *) &proposal.number, 1, DISP_DEC); display_strmap("Protocol ID", proposal.protocol_id, isakmp_protocolid_map); display("SPI size", (u_int8_t *) &proposal.spi_size, 1, DISP_DEC); display("Number of transforms", (u_int8_t *) &proposal.num_transforms, 1, DISP_DEC); if (proposal.spi_size > 0) display("SPI", (u_int8_t *) &spi, proposal.spi_size, DISP_HEX); } /* Dump the hex buffer */ hexbuffer_flush(); /* free the spi memory */ if (proposal.spi_size > 0) my_free(spi); /* Do each of the transform headers */ i = 0; while (i < proposal.num_transforms) { dump_isakmp_transform(pkt); i++; } } /*---------------------------------------------------------------------------- ** ** dump_isakmp_sa() ** ** Parse ISAKMP SA payload ** **---------------------------------------------------------------------------- */ void dump_isakmp_sa(packet_t * pkt) { isakmpgeneric_t hdr; u_int32_t doi; u_int32_t situation; /* get the generic header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0) return; /* conversions */ hdr.length = ntohs(hdr.length); if (my_args->m) { /* nothing to do here... */ } else { display_header_banner("ISAKMP/IKE SA"); display_strmap("Next payload", hdr.next_payload, isakmp_payload_map); display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC); display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC); } /* * The next 4 bytes is the DOI. We need to get it now in order to figure * out what the situation is... */ if (get_packet_bytes((u_int8_t *) &doi, pkt, 4) == 0) return; /* conversion */ doi = ntohl(doi); if (!my_args->m) display("DOI", (u_int8_t *) &doi, 4, DISP_DEC); /* get the situation based on the DOI. The IPSEC DOI situation is 4 bytes */ if (doi != ISAKMP_DOI_IPSEC) return; if (get_packet_bytes((u_int8_t *) &situation, pkt, 4) == 0) return; /* conversion */ situation = ntohl(situation); if (!my_args->m) display_strmap("Situation", situation, isakmp_doisituation_map); /* Dump the hex buffer */ hexbuffer_flush(); /* * Since an SA payload is always followed by a number of * proposal / transform payload sets, we parse then next, automatically, * then we do the given "next payload". How annoying... */ dump_isakmp_proposal(pkt); /* determine the next payload and parse it */ isakmp_next_payload(pkt, hdr.next_payload); } /*---------------------------------------------------------------------------- ** ** dump_isakmp_vendorid() ** ** Parse ISAKMP vendorid payload ** **---------------------------------------------------------------------------- */ void dump_isakmp_vendorid(packet_t * pkt) { isakmpgeneric_t hdr; u_int8_t * vendorid; int len; /* get the generic header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0) return; /* conversions */ hdr.length = ntohs(hdr.length); if (my_args->m) { /* nothing to do here... */ } else { display_header_banner("ISAKMP/IKE vendor ID"); display_strmap("Next payload", hdr.next_payload, isakmp_payload_map); display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC); display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC); } /* * This payload contains a vendor ID hash that is hdr.length - 4 bytes * First allocate memory and grab it */ len = hdr.length - sizeof(isakmpgeneric_t); vendorid = (u_int8_t *) my_malloc(len); if (get_packet_bytes(vendorid, pkt, len) == 0) { my_free(vendorid); return; } display("Vendor ID (hash)", vendorid, len, DISP_HEX_MULTILINE); /* free memory */ my_free(vendorid); /* determine the next payload and parse it */ isakmp_next_payload(pkt, hdr.next_payload); } /*---------------------------------------------------------------------------- ** ** dump_isakmp_delete() ** ** Parse ISAKMP delete payload ** **---------------------------------------------------------------------------- */ void dump_isakmp_delete(packet_t * pkt) { isakmpgeneric_t hdr; /* get the generic header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0) return; /* conversions */ hdr.length = ntohs(hdr.length); if (my_args->m) { /* nothing to do here... */ } else { display_header_banner("ISAKMP/IKE delete"); display_strmap("Next payload", hdr.next_payload, isakmp_payload_map); display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC); display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC); } } /*---------------------------------------------------------------------------- ** ** isakmp_next_payload() ** ** Call the proper payload parser based on the given next payload field ** **---------------------------------------------------------------------------- */ void isakmp_next_payload(packet_t * pkt, u_int8_t next) { switch (next) { case ISAKMP_PAYLOAD_DELETE: dump_isakmp_delete(pkt); break; case ISAKMP_PAYLOAD_SA: dump_isakmp_sa(pkt); break; case ISAKMP_PAYLOAD_VENDORID: dump_isakmp_vendorid(pkt); break; default: /* unrecognized payload, so we'll fall through and stop */ break; } } /*---------------------------------------------------------------------------- ** ** dump_isakmp() ** ** Parse ISAKMP packet and dump fields. ** **---------------------------------------------------------------------------- */ void dump_isakmp(packet_t * pkt) { isakmp_t isakmp; u_int8_t major; u_int8_t minor; u_int8_t next; u_int8_t e_flag, c_flag, a_flag; /* Set the layer */ set_layer(LAYER_APPLICATION); /* * Get the main ISAKMP header */ if (get_packet_bytes((u_int8_t *) &isakmp, pkt, sizeof(isakmp_t)) == 0) return; /* * Conversions */ isakmp.msg_id = ntohl(isakmp.msg_id); isakmp.length = ntohl(isakmp.length); next = isakmp.next_payload; major = isakmp.maj_version; minor = isakmp.min_version; e_flag = isakmp.flags & ISAKMP_FLAG_ENCRYPTION; c_flag = isakmp.flags & ISAKMP_FLAG_COMMIT; a_flag = isakmp.flags & ISAKMP_FLAG_AUTHONLY; /* * Dump header */ if (my_args->m) { /* do something here */ } else { display_header_banner("ISAKMP/IKE Header"); display("Initiatior cookie", (u_int8_t *) &isakmp.i_cookie, 8, DISP_HEX); display("Responder cookie", (u_int8_t *) &isakmp.r_cookie, 8, DISP_HEX); display_strmap("Next payload", next, isakmp_payload_map); display("Major version", (u_int8_t *) &major, 1, DISP_DEC); display("Minor version", (u_int8_t *) &minor, 1, DISP_DEC); display_strmap("Exchange type", isakmp.exchange_type, isakmp_exchange_map); display("Encryption flag", (u_int8_t *) &e_flag, 1, DISP_DEC); display("Commit flag", (u_int8_t *) &c_flag, 1, DISP_DEC); display("Auth only flag", (u_int8_t *) &a_flag, 1, DISP_DEC); display("Message ID", (u_int8_t *) &isakmp.msg_id, 4, DISP_DEC); display("Length", (u_int8_t *) &isakmp.length, 4, DISP_DEC); } /* * Dump the hex buffer */ hexbuffer_flush(); /* * Short circuit processing if this is the only header or encryption * bit is set */ if (next == ISAKMP_PAYLOAD_NONE || e_flag) { return; } /* determine the next payload and parse it */ isakmp_next_payload(pkt, next); }