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