/**************************************************************************** ** File: chap.c ** ** Author: Mike Borella ** ** Comments: CHAP decoding. ** ** $Id: chap.c,v 1.8 2001/10/02 18:37:43 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 "chap.h" /* * CHAP header */ typedef struct chap { u_int8_t code; u_int8_t identifier; u_int16_t length; } chap_t; /* * CHAP codes */ #define CHAP_CODE_CHALLENGE 1 #define CHAP_CODE_RESPONSE 2 #define CHAP_CODE_SUCCESS 3 #define CHAP_CODE_FAILURE 4 /* * CHAP code map */ strmap_t chap_code_map[] = { { CHAP_CODE_CHALLENGE, "challenge" }, { CHAP_CODE_RESPONSE, "response" }, { CHAP_CODE_SUCCESS, "success" }, { CHAP_CODE_FAILURE, "failure" }, { 0, "" } }; extern struct arg_t * my_args; /*---------------------------------------------------------------------------- ** ** dump_chap() ** ** Dump CHAP headers and payload. ** **---------------------------------------------------------------------------- */ void dump_chap(packet_t *pkt) { chap_t chap; /* Set the layer */ set_layer(LAYER_DATALINK); /* * Get the header */ if (get_packet_bytes((u_int8_t *) &chap, pkt, sizeof(chap_t)) == 0) return; /* * Conversion */ chap.length = ntohs(chap.length); /* * Dump the header */ if (my_args->m) { display_minimal_string("| CHAP "); } else { display_header_banner("CHAP Header"); display_strmap("Code", chap.code, chap_code_map); display("Identifier", &chap.identifier, 1, DISP_DEC); display("Length", (u_int8_t *) &chap.length, 2, DISP_DEC); } /* * Get the CHAP payload */ switch(chap.code) { case CHAP_CODE_CHALLENGE: case CHAP_CODE_RESPONSE: { u_int8_t * value; u_int8_t value_size; u_int8_t * name; u_int16_t name_size; /* Get the value size */ if (get_packet_bytes(&value_size, pkt, 1) == 0) return; /* Get the value */ value = (u_int8_t *) my_malloc(value_size); if (get_packet_bytes(value, pkt, value_size) == 0) { my_free(value); return; } /* Figure out the size of the name and get it */ name_size = chap.length - sizeof(chap_t) - value_size - 1; name = (u_int8_t *) my_malloc(name_size+1); if (get_packet_bytes(name, pkt, name_size) == 0) { my_free(value); my_free(name); return; } name[name_size] = '\0'; /* display everything */ if (my_args->m) { if (chap.code == CHAP_CODE_CHALLENGE) display_minimal_string("challenge "); if (chap.code == CHAP_CODE_RESPONSE) display_minimal_string("response "); display_minimal_string("("); display_minimal(value, value_size, DISP_HEX); display_minimal_string(", "); display_minimal_string(name); display_minimal_string(")"); } else { display("Value size", &value_size, 1, DISP_DEC); display("Value", value, value_size, DISP_HEX_MULTILINE); display_string("Name", name); } /* free memory */ my_free(value); my_free(name); } break; case CHAP_CODE_SUCCESS: case CHAP_CODE_FAILURE: { u_int8_t * message; u_int8_t message_len; /* figure out length of the message and then grab it */ message_len = chap.length - sizeof(chap_t); message = (u_int8_t *) my_malloc (message_len + 1); if (get_packet_bytes(message, pkt, message_len) == 0) { my_free(message); return; } message[message_len] = '\0'; /* display it */ if (my_args->m) { if (chap.code == CHAP_CODE_SUCCESS) display_minimal_string("success "); if (chap.code == CHAP_CODE_FAILURE) display_minimal_string("failure "); display_minimal_string("("); display_minimal_string(message); display_minimal_string(")"); } else { display_string("Message", message); } /* free memory */ my_free(message); } break; } }