/**************************************************************************** ** File: cbcp.c ** ** Author: Mike Borella ** ** Comments: CBCP module. This is Microsoft's Callback Control Protocol. ** ** $Id: cbcp.c,v 1.1 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 "cbcp.h" #define CBCP_OPTION_LEN 64 /* * CBCP codes */ #define CBCP_CODE_CBREQ 1 #define CBCP_CODE_CBRES 2 #define CBCP_CODE_CBACK 3 /* * CBCP code map */ strmap_t cbcp_code_map[] = { { CBCP_CODE_CBREQ, "Callback-Request" }, { CBCP_CODE_CBRES, "Callback-Response" }, { CBCP_CODE_CBACK, "Callback-Ack" }, { 0, ""} }; /* * CBCP options */ #define CBCP_OPTION_NOCALLBACK 1 #define CBCP_OPTION_CALLBACKTOUSERNUMBER 2 #define CBCP_OPTION_CALLBACKTOADMINNUMBER 3 #define CBCP_OPTION_CALLBACKTOANYLIST 4 /* * CBCP option map */ strmap_t cbcp_option_map[] = { { CBCP_OPTION_NOCALLBACK, "no callback" }, { CBCP_OPTION_CALLBACKTOUSERNUMBER, "callback to user defined number" }, { CBCP_OPTION_CALLBACKTOADMINNUMBER, "callback to admin defined number" }, { CBCP_OPTION_CALLBACKTOANYLIST, "callback to any list of numbers" }, { 0, "" } }; /* * CBCP frame format */ typedef struct cbcp { u_int8_t code; u_int8_t identifier; u_int16_t length; } cbcp_t; extern struct arg_t * my_args; /*---------------------------------------------------------------------------- ** ** dump_cbcp() ** ** Displays CBCP packets. ** **---------------------------------------------------------------------------- */ void dump_cbcp(packet_t *pkt) { cbcp_t cbcp; /* Set the layer */ set_layer(LAYER_DATALINK); /* * Get the header */ if (get_packet_bytes((u_int8_t *) &cbcp, pkt, sizeof(cbcp_t)) == 0) return; /* * Conversion */ cbcp.length = ntohs(cbcp.length); /* * Dump the header */ if (my_args->m) { display_minimal_string("| CBCP "); display_minimal_string(map2str(cbcp_code_map, cbcp.code)); display_minimal_string(" "); } else { display_header_banner("CBCP Header"); display_strmap("Code", cbcp.code, cbcp_code_map); display("Identifier", &cbcp.identifier, 1, DISP_DEC); display("Length", (u_int8_t *) &cbcp.length, 2, DISP_DEC); } /* * Grab the payload data */ if (cbcp.length > sizeof(cbcp_t)) { switch(cbcp.code) { case CBCP_CODE_CBREQ: case CBCP_CODE_CBRES: case CBCP_CODE_CBACK: { u_int8_t bytes_read = 0; u_int8_t type; u_int8_t length; u_int8_t value [CBCP_OPTION_LEN]; int comma = 0; /* * CBCP options appear in Type-Length-Value format */ while (bytes_read < cbcp.length - sizeof(cbcp_t)) { /* * Get type */ if (get_packet_bytes((u_int8_t *) &type, pkt, 1) == 0) break; bytes_read ++; /* * Get length */ if (get_packet_bytes((u_int8_t *) &length, pkt, 1) == 0) break; bytes_read ++; /* * In minimal mode we start all CBCP options with an open paren * and put a comma before all but the first */ if (my_args->m) { if (comma) display_minimal_string(", "); else display_minimal_string("("); } comma = 1; /* * Display the type and length */ if (my_args->m) { display_minimal_string(map2str(cbcp_option_map, type)); } else { display_strmap("Option", type, cbcp_option_map); display(" Length", &length, 1, DISP_DEC); } /* * Figure out if we need to get a value */ if (length > 2) { if (get_packet_bytes((u_int8_t *) value, pkt, length-2) == 0) break; bytes_read = bytes_read + length - 2; /* * Display the value */ if (my_args->m) { display_minimal_string(" "); display_minimal(value, length-2, DISP_HEX); } else { display(" Value", (u_int8_t *) value, length-2, DISP_HEX); } } /* if */ } /* while */ /* * Insert end paren in minimal mode */ if (my_args->m) display_minimal_string(")"); } break; default: break; } } /* dump the hex buffer */ if (!my_args->l) hexbuffer_flush(); }