/****************************************************************************
**
** 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);
}
syntax highlighted by Code2HTML, v. 0.9.1