/****************************************************************************
** File: mobileip.c
**
** Author: Mike Borella
**
** Comments:
**
** $Id: mobileip.c,v 1.10 2001/09/07 20:59:11 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 "global.h"
#include "mobileip.h"
#include "ethertypes.h"
/*
* Types of Mobile IP messages
*/
#define MOBILEIP_TYPE_REGREQ 1
#define MOBILEIP_TYPE_REGREP 3
#define MOBILEIP_TYPE_REGUPDATE 20
#define MOBILEIP_TYPE_REGACK 21
/*
* Mobile IP type map
*/
strmap_t mobileip_type_map[] =
{
{ MOBILEIP_TYPE_REGREQ, "registration request" },
{ MOBILEIP_TYPE_REGREP, "registration reply" },
{ MOBILEIP_TYPE_REGUPDATE, "registration update" },
{ MOBILEIP_TYPE_REGACK, "registration acknowledgement" },
{ 0, ""}
};
/*
* Mobile IP response codes
*/
#define MOBILEIP_RESPCODE_REGACCEPTED 0
#define MOBILEIP_RESPCODE_REGACCEPTEDNOSMB 1
#define MOBILEIP_RESPCODE_FA_UNSPECIFIED 64
#define MOBILEIP_RESPCODE_FA_ADMINPROHIBITED 65
#define MOBILEIP_RESPCODE_FA_INSUFFICIENTRESOURCES 66
#define MOBILEIP_RESPCODE_FA_MNAUTHFAILED 67
#define MOBILEIP_RESPCODE_FA_HAAUTHFAILED 68
#define MOBILEIP_RESPCODE_FA_LIFETIMETOOLONG 69
#define MOBILEIP_RESPCODE_FA_POORLYFORMEDREQ 70
#define MOBILEIP_RESPCODE_FA_POORLYFORMEDREP 71
#define MOBILEIP_RESPCODE_FA_ENCAPSUNAVAILABLE 72
#define MOBILEIP_RESPCODE_FA_VJCOMPUNAVAILABLE 73
#define MOBILEIP_RESPCODE_FA_HNUNREACHABLE 80
#define MOBILEIP_RESPCODE_FA_HAHOSTUNREACHABLE 81
#define MOBILEIP_RESPCODE_FA_HAPORTUNREACHABLE 82
#define MOBILEIP_RESPCODE_FA_HAUNREACHABLE 88
#define MOBILEIP_RESPCODE_HA_UNSPECIFIED 128
#define MOBILEIP_RESPCODE_HA_ADMINPROHIBITED 129
#define MOBILEIP_RESPCODE_HA_INSUFFICIENTRESOURCES 130
#define MOBILEIP_RESPCODE_HA_MNAUTHFAILED 131
#define MOBILEIP_RESPCODE_HA_FAAUTHFAILED 132
#define MOBILEIP_RESPCODE_HA_IDMISMATCH 133
#define MOBILEIP_RESPCODE_HA_POORLYFORMEDREQ 134
#define MOBILEIP_RESPCODE_HA_TOOMANYSMB 135
#define MOBILEIP_RESPCODE_HA_UNKNOWNHAADDR 136
/*
* Mobile IP extensions
*/
#define MOBILEIP_EXT_MHAUTH 32 /* RFC 2002 */
#define MOBILEIP_EXT_MFAUTH 33 /* RFC 2002 */
#define MOBILEIP_EXT_FHAUTH 34 /* RFC 2002 */
#define MOBILEIP_EXT_GENMOBILEIPAUTH 36 /* RFC 3012 */
#define MOBILEIP_EXT_CVSE 38 /* RFC 3025 */
#define MOBILEIP_EXT_SESSIONSPECIFIC 39 /* TIA/IS-2001 */
#define MOBILEIP_EXT_REGUPDATEAUTH 40 /* TIA/IS-2001 */
#define MOBILEIP_EXT_NAI 131 /* RFC 2794 */
#define MOBILEIP_EXT_MNFACHALLENGE 132 /* RFC 2794 */
/*
* Mobile IP extension map
*/
strmap_t mobileip_ext_map [] =
{
{ MOBILEIP_EXT_MHAUTH, "mobile-home authentication" },
{ MOBILEIP_EXT_MFAUTH, "mobile-foreign authentication" },
{ MOBILEIP_EXT_FHAUTH, "foreign-home authentication" },
{ MOBILEIP_EXT_GENMOBILEIPAUTH, "generalized Mobile IP authentication" },
{ MOBILEIP_EXT_CVSE, "critical vendor-specific extension" },
{ MOBILEIP_EXT_SESSIONSPECIFIC, "session specific extension" },
{ MOBILEIP_EXT_REGUPDATEAUTH, "registration update authentication" },
{ MOBILEIP_EXT_NAI, "network access identifier" },
{ MOBILEIP_EXT_MNFACHALLENGE, "MN-FA challenge" },
{ 0, "" }
};
/*
* Format of Mobile IP registration request
*
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type |S|B|D|M|G|V|rsv| Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Agent |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Care-of Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + Identification +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Extensions ...
* +-+-+-+-+-+-+-+-
*/
typedef struct mobileip_regreq
{
u_int8_t type;
u_int8_t flags;
u_int16_t lifetime;
u_int32_t home_addr;
u_int32_t home_agent;
u_int32_t care_of_addr;
u_int8_t identification[8];
} mobileip_regreq_t;
/*
* Format of Mobile IP registration reply
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Code | Lifetime |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Agent |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + Identification +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Extensions ...
* +-+-+-+-+-+-+-+-
*/
typedef struct mobileip_regrep
{
u_int8_t type;
u_int8_t code;
u_int16_t lifetime;
u_int32_t home_addr;
u_int32_t home_agent;
u_int8_t identification[8];
} mobileip_regrep_t;
/*
* Format of Mobile IP registration update
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Agent Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + Identification +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Extensions ...
* +-+-+-+-+-+-+-+-
*/
typedef struct mobileip_regupdate
{
u_int8_t type;
u_int8_t reserved[3];
u_int32_t home_addr;
u_int32_t home_agent;
u_int8_t identification[8];
} mobileip_regupdate_t;
/*
* Format of Mobile IP registration ack
*
* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Type | Status | Reserved |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Address |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Home Agent |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | |
* + Identification +
* | |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | Extensions ...
* +-+-+-+-+-+-+-+-
*/
typedef struct mobileip_regack
{
u_int8_t type;
u_int8_t status;
u_int16_t reserved;
u_int32_t home_addr;
u_int32_t home_agent;
u_int8_t identification[8];
} mobileip_regack_t;
/*
* Structure of the Mobile IP session specific extension
*/
typedef struct mobileip_ext_sessionspecific
{
u_int8_t type;
u_int8_t length;
u_int16_t protocol;
u_int32_t key;
u_int16_t reserved;
u_int16_t mn_session;
u_int16_t mn_id_type;
u_int8_t mn_id_length;
} mobileip_ext_sessionspecific_t;
/*
* Structure of the mobile IP CVSE
*/
typedef struct mobileip_ext_cvse
{
u_int8_t type;
u_int8_t reserved;
u_int16_t length;
u_int32_t vendor;
u_int16_t subtype;
} mobileip_ext_cvse_t;
/*
* Structure of the mobile IP mobile/home authentication extension
*/
typedef struct mobileip_ext_mhauth
{
u_int8_t type;
u_int8_t length;
u_int32_t spi;
} mobileip_ext_mhauth_t;
/*
* Structure of the fixed portion of the general mobile IP auth extension
*/
typedef struct mobileip_ext_genmobileipauth
{
u_int8_t type;
u_int8_t subtype;
u_int16_t length;
u_int32_t spi;
} mobileip_ext_genmobileipauth_t;
extern struct arg_t * my_args;
extern strmap_t ethertype_map[];
/*----------------------------------------------------------------------------
**
** dump_mobileip_sessionspecificext()
**
** Dumps mobile IP session specific extensions
**
**----------------------------------------------------------------------------
*/
void dump_mobileip_ext_sessionspecific(packet_t *pkt)
{
mobileip_ext_sessionspecific_t ss;
u_int8_t * mn_id;
/* Get the common part of the extension */
if (get_packet_bytes((u_int8_t *) &ss, pkt, 15) == 0)
return;
/* Conversions */
ss.protocol = ntohs(ss.protocol);
ss.key = ntohl(ss.key);
ss.reserved = ntohs(ss.reserved);
ss.mn_session = ntohs(ss.mn_session);
ss.mn_id_type = ntohs(ss.mn_id_type);
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_ext_map, ss.type));
display_minimal_string(" ");
}
else
{
display_strmap("Extension type", ss.type, mobileip_ext_map);
display(" Length", &ss.length, 1, DISP_DEC);
display_strmap_hex(" Protocol", ss.protocol, ethertype_map);
display(" Key", (u_int8_t *) &ss.key, 4, DISP_HEX);
display(" Reserved", (u_int8_t *) &ss.reserved, 2, DISP_DEC);
display(" MN session ref ID", (u_int8_t *) &ss.mn_session, 2, DISP_DEC);
display(" MN ID type", (u_int8_t *) &ss.mn_id_type, 2, DISP_DEC);
display(" MN ID length", (u_int8_t *) &ss.mn_id_length, 1, DISP_DEC);
}
/* Allocate memeory for the MN ID */
mn_id = my_malloc(ss.mn_id_length);
/* Get the MN ID */
if (get_packet_bytes(mn_id, pkt, ss.mn_id_length) == 0)
return;
/* Display the MN ID */
if (my_args->m)
{
}
else
display(" MN ID", mn_id, ss.mn_id_length, DISP_HEX);
/* Deallocate memory for the MN ID */
my_free(mn_id);
/*
* Check for any padding. Some PCF's send a full 21 byte option
* regardless of the length of the MN ID. The fixed portion of the
* option is 13 bytes.
*/
if (ss.mn_id_length + 13 < ss.length)
{
u_int16_t dummy;
if (get_packet_bytes((u_int8_t *) &dummy, pkt,
ss.length - ss.mn_id_length - 13) == 0)
return;
}
return;
}
/*----------------------------------------------------------------------------
**
** dump_mobileip_ext_csve()
**
** Dumps mobile IP critical / vendor specific extensions
**
**----------------------------------------------------------------------------
*/
void dump_mobileip_ext_cvse(packet_t * pkt)
{
mobileip_ext_cvse_t cvse;
u_int8_t * data;
/* Get the common part of the header */
if (get_packet_bytes((u_int8_t *) &cvse, pkt, 10) == 0)
return;
/* Conversions */
cvse.length = ntohs(cvse.length);
cvse.vendor = ntohl(cvse.vendor);
cvse.subtype = ntohs(cvse.subtype);
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_ext_map, cvse.type));
display_minimal_string(" ");
}
else
{
display_strmap("Extention type", cvse.type, mobileip_ext_map);
display(" Reserved", &cvse.reserved, 1, DISP_DEC);
display(" Length", (u_int8_t *) &cvse.length, 2, DISP_DEC);
display(" Vendor ID", (u_int8_t *) &cvse.vendor, 4, DISP_DEC);
display(" Subtype", (u_int8_t *) &cvse.subtype, 2, DISP_DEC);
}
if (cvse.length > 6)
{
/* Allocate memory for data */
data = my_malloc(cvse.length-6);
/* Get data portion */
if (get_packet_bytes(data, pkt, cvse.length-6) == 0)
return;
/* Display data portion */
if (!my_args->m)
display(" Data", data, cvse.length-6, DISP_HEX_MULTILINE);
/* Free memory for data */
my_free(data);
}
}
/*----------------------------------------------------------------------------
**
** dump_mobileip_ext_nai()
**
** Dumps mobile IP NAI extension
**
**----------------------------------------------------------------------------
*/
void dump_mobileip_ext_nai(packet_t * pkt)
{
u_int8_t type;
u_int8_t length;
char * nai;
/* Get the type */
if (get_packet_bytes((u_int8_t *) &type, pkt, 1) == 0)
return;
/* Get the length */
if (get_packet_bytes((u_int8_t *) &length, pkt, 1) == 0)
return;
/* Get the NAI */
nai = (char *) malloc (length+2);
if (get_packet_bytes(nai, pkt, length) == 0)
return;
nai[length] = '\0';
/* Display */
if (my_args->m)
{
}
else
{
display_strmap("Extension type", type, mobileip_ext_map);
display(" Length", (u_int8_t *) &length, 1, DISP_DEC);
display_string(" NAI", nai);
}
/* Free memory */
my_free(nai);
return;
}
/*----------------------------------------------------------------------------
**
** dump_mobileip_ext_mnfachallenge()
**
** Dumps mobile IP MN-FA extension
**
**----------------------------------------------------------------------------
*/
void dump_mobileip_ext_mnfachallenge(packet_t * pkt)
{
u_int8_t type;
u_int8_t length;
u_int8_t * challenge;
/* Get the type */
if (get_packet_bytes((u_int8_t *) &type, pkt, 1) == 0)
return;
/* Get the length */
if (get_packet_bytes((u_int8_t *) &length, pkt, 1) == 0)
return;
/* Get the authenticator */
challenge = (char *) malloc (length+2);
if (get_packet_bytes((u_int8_t *) challenge, pkt, length) == 0)
return;
/* Display */
if (my_args->m)
{
}
else
{
display_strmap("Extension type", type, mobileip_ext_map);
display(" Length", (u_int8_t *) &length, 1, DISP_DEC);
display(" Challenge", (u_int8_t *) challenge, length, DISP_HEX);
}
/* Free memory */
my_free(challenge);
return;
}
/*----------------------------------------------------------------------------
**
** dump_mobileip_ext_genmobileipauth()
**
** Dumps the general MIP authentication extension
**
**----------------------------------------------------------------------------
*/
void dump_mobileip_ext_genmobileipauth(packet_t * pkt)
{
mobileip_ext_genmobileipauth_t genmip;
u_int8_t * auth;
/* Get the fixed header */
if (get_packet_bytes((u_int8_t *) &genmip, pkt, 8) == 0)
return;
/* Conversions */
genmip.length = ntohs(genmip.length);
/* Allocate memory for the authentication */
auth = my_malloc(genmip.length-4);
/* Get the authenticator */
if (get_packet_bytes(auth, pkt, genmip.length-4) == 0)
return;
/* Display */
if (my_args->m)
{
}
else
{
display_strmap("Extension type", genmip.type, mobileip_ext_map);
display(" Subtype", &genmip.subtype, 1, DISP_DEC);
display(" Length", (u_int8_t *) &genmip.length, 2, DISP_DEC);
display(" SPI", (u_int8_t *) &genmip.spi, 4, DISP_HEX);
display(" Authenticator", auth, genmip.length-4, DISP_HEX_MULTILINE);
}
/* Free memory for authenticator */
my_free(auth);
return;
}
/*----------------------------------------------------------------------------
**
** dump_mobileip_ext_mhauth()
**
** Dumps mobile IP mobile/home authentication extension messages
**
**----------------------------------------------------------------------------
*/
void dump_mobileip_ext_mhauth(packet_t * pkt)
{
mobileip_ext_mhauth_t mh;
u_int8_t * authenticator;
/* Read all but the authenticator */
if (get_packet_bytes((u_int8_t *) &mh, pkt, 6) == 0)
return;
/* Conversions */
mh.spi = ntohl(mh.spi);
/* Allocate memory for authenticator */
authenticator = my_malloc(mh.length-4);
/* Read authenticator */
if (get_packet_bytes(authenticator, pkt, mh.length-4) == 0)
return;
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_ext_map, mh.type));
display_minimal_string(" ");
}
else
{
display_strmap("Extension type", mh.type, mobileip_ext_map);
display(" Length", &mh.length, 1, DISP_DEC);
display(" SPI", (u_int8_t *) &mh.spi, 4, DISP_HEX);
display(" Authenticator", authenticator, mh.length-4,
DISP_HEX_MULTILINE);
}
/* Free memory for authenticator */
my_free(authenticator);
return;
}
/*----------------------------------------------------------------------------
**
** dump_mobileip()
**
** Dumps mobile IP messages
**
**----------------------------------------------------------------------------
*/
void dump_mobileip(packet_t *pkt)
{
u_int8_t first_byte;
/* Set the layer */
set_layer(LAYER_APPLICATION);
/*
* Look at the first byte to determine the type
*/
if (look_packet_bytes(&first_byte, pkt, 1) == 0)
return;
/*
* Display mobile IP annoucnement
*/
if (my_args->m)
display_minimal_string("| Mobile IP ");
else
display_header_banner("Mobile IP");
/*
* Take action based on message type
*/
switch(first_byte)
{
case MOBILEIP_TYPE_REGREQ: /* registration request */
{
mobileip_regreq_t regreq;
/* Get the message */
if (get_packet_bytes((u_int8_t *) ®req, pkt, sizeof(regreq)) == 0)
return;
/* Conversions */
regreq.lifetime = ntohs(regreq.lifetime);
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_type_map, regreq.type));
display_minimal_string(" (");
display_minimal_string("addr:");
display_minimal_ipv4((u_int8_t *) ®req.home_addr);
display_minimal_string(",HA:");
display_minimal_ipv4((u_int8_t *) ®req.home_agent);
display_minimal_string(",COA:");
display_minimal_ipv4((u_int8_t *) ®req.care_of_addr);
display_minimal_string(") ");
}
else
{
display_strmap("Type", regreq.type, mobileip_type_map);
display("Flags", ®req.flags, 1, DISP_HEX);
display("Lifetime", (u_int8_t *) ®req.lifetime, 2, DISP_DEC);
display_ipv4("Home address", (u_int8_t *) ®req.home_addr);
display_ipv4("Home agent", (u_int8_t *) ®req.home_agent);
display_ipv4("Care of address", (u_int8_t *) ®req.care_of_addr);
display("Identification", (u_int8_t *) ®req.identification, 8,
DISP_HEX);
}
}
break;
case MOBILEIP_TYPE_REGREP: /* registration response */
{
mobileip_regrep_t regrep;
/* Get the message */
if (get_packet_bytes((u_int8_t *) ®rep, pkt, sizeof(regrep)) == 0)
return;
/* Conversions */
regrep.lifetime = ntohs(regrep.lifetime);
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_type_map, regrep.type));
display_minimal_string(" (");
display_minimal_string("addr:");
display_minimal_ipv4((u_int8_t *) ®rep.home_addr);
display_minimal_string(",HA:");
display_minimal_ipv4((u_int8_t *) ®rep.home_agent);
display_minimal_string(") ");
}
else
{
display_strmap("Type", regrep.type, mobileip_type_map);
display("Code", ®rep.code, 1, DISP_HEX);
display("Lifetime", (u_int8_t *) ®rep.lifetime, 2, DISP_DEC);
display_ipv4("Home address", (u_int8_t *) ®rep.home_addr);
display_ipv4("Home agent", (u_int8_t *) ®rep.home_agent);
display("Identification", (u_int8_t *) ®rep.identification, 8,
DISP_HEX);
}
}
break;
case MOBILEIP_TYPE_REGUPDATE: /* registration update */
{
mobileip_regupdate_t regupdate;
/* Get the message */
if (get_packet_bytes((u_int8_t *) ®update, pkt, sizeof(regupdate))
== 0)
return;
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_type_map, regupdate.type));
display_minimal_string(" (");
display_minimal_string("addr:");
display_minimal_ipv4((u_int8_t *) ®update.home_addr);
display_minimal_string(",HA:");
display_minimal_ipv4((u_int8_t *) ®update.home_agent);
display_minimal_string(") ");
}
else
{
display_strmap("Type", regupdate.type, mobileip_type_map);
display("Reserved", (u_int8_t *) ®update.reserved, 3, DISP_DEC);
display_ipv4("Home address", (u_int8_t *) ®update.home_addr);
display_ipv4("Home agent", (u_int8_t *) ®update.home_agent);
display("Identification", (u_int8_t *) ®update.identification,
8, DISP_HEX);
}
}
break;
case MOBILEIP_TYPE_REGACK: /* registration ack */
{
mobileip_regack_t regack;
/* Get the message */
if (get_packet_bytes((u_int8_t *) ®ack, pkt, sizeof(regack)) == 0)
return;
/* Conversions */
regack.reserved = ntohs(regack.reserved);
/* Display */
if (my_args->m)
{
display_minimal_string(map2str(mobileip_type_map, regack.type));
display_minimal_string(" (");
display_minimal_string("addr:");
display_minimal_ipv4((u_int8_t *) ®ack.home_addr);
display_minimal_string(",HA:");
display_minimal_ipv4((u_int8_t *) ®ack.home_agent);
display_minimal_string(") ");
}
else
{
display_strmap("Type", regack.type, mobileip_type_map);
display("Status", ®ack.status, 1, DISP_HEX);
display("Reserved", (u_int8_t *) ®ack.reserved, 2, DISP_DEC);
display_ipv4("Home address", (u_int8_t *) ®ack.home_addr);
display_ipv4("Home agent", (u_int8_t *) ®ack.home_agent);
display("Identification", (u_int8_t *) ®ack.identification, 8,
DISP_HEX);
}
}
break;
default: /* Unknown message type, dump the hexbuffer and quit */
hexbuffer_flush();
return;
}
/*
* Look for extensions. Note that since not all mobile IP extensions
* follow the RFC 2002 method (type-length-value) we may cause weird
* problems by assuming that there is a valid length after the type.
*/
while (get_packet_apparentbytesleft(pkt))
{
u_int8_t type;
/* Get the next byte, which should be the type of the extension */
if (look_packet_bytes(&type, pkt, 1) == 0)
{
hexbuffer_flush();
return;
}
/* Decide what to do based on the extension type */
switch(type)
{
case MOBILEIP_EXT_SESSIONSPECIFIC:
dump_mobileip_ext_sessionspecific(pkt);
break;
case MOBILEIP_EXT_CVSE:
dump_mobileip_ext_cvse(pkt);
break;
case MOBILEIP_EXT_MHAUTH:
case MOBILEIP_EXT_REGUPDATEAUTH:
dump_mobileip_ext_mhauth(pkt);
break;
case MOBILEIP_EXT_NAI:
dump_mobileip_ext_nai(pkt);
break;
case MOBILEIP_EXT_MNFACHALLENGE:
dump_mobileip_ext_mnfachallenge(pkt);
break;
case MOBILEIP_EXT_GENMOBILEIPAUTH:
dump_mobileip_ext_genmobileipauth(pkt);
break;
default: /* We don't recognize this extension...just dump the data */
{
u_int8_t type;
u_int8_t length;
u_int8_t * data;
/* Get the type and the length */
if (get_packet_bytes(&type, pkt, 1) == 0)
return;
if (get_packet_bytes(&length, pkt, 1) == 0)
return;
/* Display the type and the length */
if (my_args->m)
{
}
else
{
display_strmap("Extension type", type, mobileip_ext_map);
display(" Length", &length, 1, DISP_DEC);
}
/* Allocate memory for the data */
data = my_malloc(length);
/* Get the data */
if (get_packet_bytes(data, pkt, length) == 0)
{
hexbuffer_flush();
return;
}
/*
* Dump the data. Let's not do anything for minimal mode because
* it would probably just clutter the display
*/
if (!my_args->m)
{
display(" Data", data, length, DISP_HEX_MULTILINE);
}
/* Deallocate memory for the data */
my_free(data);
}
break;
}
}
/* Dump the hex buffer */
hexbuffer_flush();
return;
}
syntax highlighted by Code2HTML, v. 0.9.1