/**************************************************************************** ** File: pptp.c ** ** Author: Mike Borella ** ** Comments: Dump PPTP information ** ** $Id: pptp.c,v 1.12 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 "global.h" #include "ip_protocols.h" #include "pptp.h" extern struct arg_t *my_args; /* * PPTP message type map */ strmap_t pptp_msgtype_map[] = { { PPTP_MSGTYPE_CONTROL, "control" }, { PPTP_MSGTYPE_MANAGEMENT, "management" } }; #define PPTP_MSGTYPE_CONTROL 1 #define PPTP_MSGTYPE_MANAGEMENT 2 /* * PPTP control message types */ strmap_t pptp_cntlmsgtype_map[] = { { PPTP_CNTLMSGTYPE_STARTCCREQ, "Start-Control-Connection-Request" }, { PPTP_CNTLMSGTYPE_STARTCCREP, "Start-Control-Connection-Reply" }, { PPTP_CNTLMSGTYPE_STOPCCREQ, "Stop-Control-Connection-Request" }, { PPTP_CNTLMSGTYPE_STOPCCREP, "Stop-Control-Connection-Reply" }, { PPTP_CNTLMSGTYPE_ECHOREQ, "Echo-Request" }, { PPTP_CNTLMSGTYPE_ECHOREP, "Echo-Reply" }, { PPTP_CNTLMSGTYPE_OUTGOINGREQ, "Outgoing-Call-Request" }, { PPTP_CNTLMSGTYPE_OUTGOINGREP, "Outgoing-Call-Reply" }, { PPTP_CNTLMSGTYPE_INCOMINGREQ, "Incoming-Call-Request" }, { PPTP_CNTLMSGTYPE_INCOMINGREP, "Incoming-Call-Reply" }, { PPTP_CNTLMSGTYPE_INCOMINGCONN, "Incoming-Call-Connected" }, { PPTP_CNTLMSGTYPE_CALLCLEARREQ, "Call-Clear-Request" }, { PPTP_CNTLMSGTYPE_CALLDISCNTFY, "Call-Disconnect-Notify" }, { PPTP_CNTLMSGTYPE_WANERRORNTFY, "WAN-Error-Notify" }, { PPTP_CNTLMSGTYPE_SETLINKINFO, "Set-Link-Info" }, { 0, "" } }; /*---------------------------------------------------------------------------- ** ** dump_pptp_startccreq() ** ** Parse PPTP Start-Control-Connection-Request ** **---------------------------------------------------------------------------- */ void dump_pptp_startccreq(packet_t *pkt) { pptp_startccreq_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_startccreq_t)) == 0) return; /* * Conversions */ hdr.version = ntohs(hdr.version); hdr.reserved1 = ntohs(hdr.reserved1); hdr.framing_cap = ntohl(hdr.framing_cap); hdr.bearer_cap = ntohl(hdr.bearer_cap); hdr.max_channels = ntohs(hdr.max_channels); hdr.firmware_rev = ntohs(hdr.firmware_rev); hdr.hostname[PPTP_HOSTNAME_LEN-1] = '\0'; hdr.vendor[PPTP_VENDOR_LEN-1] = '\0'; /* * Display */ if (my_args->m) { display_minimal_string(hdr.hostname); display_minimal_string(" "); } else { display("Version", (u_int8_t *) &hdr.version, 2, DISP_DEC); display("Reserved", (u_int8_t *) &hdr.reserved1, 2, DISP_DEC); display("Framing capabilities", (u_int8_t *) &hdr.framing_cap, 4, DISP_DEC); display("Bearer capabilities", (u_int8_t *) &hdr.bearer_cap, 4, DISP_DEC); display("Max channels", (u_int8_t *) &hdr.max_channels, 2, DISP_DEC); display("Firmware revision", (u_int8_t *) &hdr.firmware_rev, 2, DISP_DEC); display_string("Host name", hdr.hostname); display_string("Vendor", hdr.vendor); } } /*---------------------------------------------------------------------------- ** ** dump_pptp_startccrep() ** ** Parse PPTP Start-Control-Connection-Reply ** **---------------------------------------------------------------------------- */ void dump_pptp_startccrep(packet_t *pkt) { pptp_startccrep_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_startccrep_t)) == 0) return; /* * Conversions */ hdr.version = ntohs(hdr.version); hdr.framing_cap = ntohl(hdr.framing_cap); hdr.bearer_cap = ntohl(hdr.bearer_cap); hdr.max_channels = ntohs(hdr.max_channels); hdr.firmware_rev = ntohs(hdr.firmware_rev); hdr.hostname[PPTP_HOSTNAME_LEN-1] = '\0'; hdr.vendor[PPTP_VENDOR_LEN-1] = '\0'; /* * Display */ if (my_args->m) { display_minimal_string(hdr.hostname); display_minimal_string(" "); } else { display("Version", (u_int8_t *) &hdr.version, 2, DISP_DEC); display("Result code", (u_int8_t *) &hdr.result_code, 1, DISP_DEC); display("Error code", (u_int8_t *) &hdr.error_code, 1, DISP_DEC); display("Framing capabilities", (u_int8_t *) &hdr.framing_cap, 4, DISP_DEC); display("Bearer capabilities", (u_int8_t *) &hdr.bearer_cap, 4, DISP_DEC); display("Max channels", (u_int8_t *) &hdr.max_channels, 2, DISP_DEC); display("Firmware revision", (u_int8_t *) &hdr.firmware_rev, 2, DISP_DEC); display_string("Host name", hdr.hostname); display_string("Vendor", hdr.vendor); } } /*---------------------------------------------------------------------------- ** ** dump_pptp_outgoingreq() ** ** Parse PPTP Outgoing-Call-Request ** **---------------------------------------------------------------------------- */ void dump_pptp_outgoingreq(packet_t *pkt) { pptp_outgoingreq_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_outgoingreq_t)) == 0) return; /* * Conversions */ hdr.call_id = ntohs(hdr.call_id); hdr.call_sn = ntohs(hdr.call_sn); hdr.min_bps = ntohl(hdr.min_bps); hdr.max_bps = ntohl(hdr.max_bps); hdr.bearer_type = ntohl(hdr.bearer_type); hdr.framing_type = ntohl(hdr.framing_type); hdr.recv_window_size = ntohs(hdr.recv_window_size); hdr.packet_proc_delay = ntohs(hdr.packet_proc_delay); hdr.phone_num_len = ntohs(hdr.phone_num_len); hdr.reserved1 = ntohs(hdr.reserved1); hdr.phone_num[PPTP_PHONENUM_LEN-1] = '\0'; hdr.phone_num[hdr.phone_num_len] = '\0'; hdr.subaddress[PPTP_SUBADDRESS_LEN-1] = '\0'; /* * Display */ if (my_args->m) { display_minimal_string(hdr.phone_num); display_minimal_string(" "); } else { display("Call ID", (u_int8_t *) &hdr.call_id, 2, DISP_DEC); display("Call serial number", (u_int8_t *) &hdr.call_sn, 2, DISP_DEC); display("Minimum BPS", (u_int8_t *) &hdr.min_bps, 4, DISP_DEC); display("Maximum BPS", (u_int8_t *) &hdr.max_bps, 4, DISP_DEC); display("Bearer type", (u_int8_t *) &hdr.bearer_type, 4, DISP_DEC); display("Framing type", (u_int8_t *) &hdr.framing_type, 4, DISP_DEC); display("Receive window size", (u_int8_t *) &hdr.recv_window_size, 2, DISP_DEC); display("Packet processing delay", (u_int8_t *) &hdr.packet_proc_delay, 2, DISP_DEC); display("Phone number length", (u_int8_t *) &hdr.phone_num_len, 2, DISP_DEC); display("Reserved", (u_int8_t *) &hdr.reserved1, 2, DISP_DEC); display_string("Phone number", hdr.phone_num); display_string("Subaddress", hdr.subaddress); } } /*---------------------------------------------------------------------------- ** ** dump_pptp_outgoingrep() ** ** Parse PPTP Outgoing-Call-Reply ** **---------------------------------------------------------------------------- */ void dump_pptp_outgoingrep(packet_t *pkt) { pptp_outgoingrep_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_outgoingrep_t)) == 0) return; /* * Conversions */ hdr.call_id = ntohs(hdr.call_id); hdr.peer_call_id = ntohs(hdr.peer_call_id); hdr.cause_code = ntohs(hdr.cause_code); hdr.connect_speed = ntohl(hdr.connect_speed); hdr.recv_window_size = ntohs(hdr.recv_window_size); hdr.packet_proc_delay = ntohs(hdr.packet_proc_delay); hdr.phy_channel_id = ntohl(hdr.phy_channel_id); /* * Display */ if (my_args->m) { /* XXX fix me ! */ display_minimal_string(" "); } else { display("Call ID", (u_int8_t *) &hdr.call_id, 2, DISP_DEC); display("Peer call ID", (u_int8_t *) &hdr.peer_call_id, 2, DISP_DEC); display("Result code", (u_int8_t *) &hdr.result_code, 1, DISP_DEC); display("Error code", (u_int8_t *) &hdr.error_code, 1, DISP_DEC); display("Cause code", (u_int8_t *) &hdr.cause_code, 2, DISP_DEC); display("Connect speed", (u_int8_t *) &hdr.connect_speed, 4, DISP_DEC); display("Receive window size", (u_int8_t *) &hdr.recv_window_size, 2, DISP_DEC); display("Packet processing delay", (u_int8_t *) &hdr.packet_proc_delay, 2, DISP_DEC); display("Physical channel ID", (u_int8_t *) &hdr.phy_channel_id, 4, DISP_DEC); } } /*---------------------------------------------------------------------------- ** ** dump_pptp_setlinkinfo() ** ** Parse PPTP Set-Link-Info ** **---------------------------------------------------------------------------- */ void dump_pptp_setlinkinfo(packet_t *pkt) { pptp_setlinkinfo_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_setlinkinfo_t)) == 0) return; /* * Conversions */ hdr.peer_call_id = ntohs(hdr.peer_call_id); hdr.reserved1 = ntohs(hdr.reserved1); hdr.send_accm = ntohl(hdr.send_accm); hdr.receive_accm = ntohl(hdr.receive_accm); /* * Display */ if (my_args->m) { /* XXX fix me ! */ display_minimal_string(" "); } else { display("Peer call ID", (u_int8_t *) &hdr.peer_call_id, 2, DISP_DEC); display("Reserved", (u_int8_t *) &hdr.reserved1, 2, DISP_DEC); display("Send ACCM", (u_int8_t *) &hdr.send_accm, 4, DISP_HEX); display("Receive ACCM", (u_int8_t *) &hdr.receive_accm, 4, DISP_HEX); } } /*---------------------------------------------------------------------------- ** ** dump_pptp_callclearreq() ** ** Parse PPTP Call-Clear-Request ** **---------------------------------------------------------------------------- */ void dump_pptp_callclearreq(packet_t *pkt) { pptp_callclearreq_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_callclearreq_t)) == 0) return; /* * Conversions */ hdr.call_id = ntohs(hdr.call_id); hdr.reserved = ntohs(hdr.reserved); /* * Display */ if (my_args->m) { /* XXX fix me ! */ display_minimal_string(" "); } else { display("Call ID", (u_int8_t *) &hdr.call_id, 2, DISP_DEC); display("Reserved", (u_int8_t *) &hdr.reserved, 2, DISP_DEC); } } /*---------------------------------------------------------------------------- ** ** dump_pptp_calldiscntfy() ** ** Parse PPTP Call-Disconnect-Notify ** **---------------------------------------------------------------------------- */ void dump_pptp_calldiscntfy(packet_t *pkt) { pptp_calldiscntfy_t hdr; /* * Get the header */ if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(pptp_calldiscntfy_t)) == 0) return; /* * Conversions */ hdr.call_id = ntohs(hdr.call_id); hdr.cause_code = ntohs(hdr.cause_code); hdr.reserved = ntohs(hdr.reserved); /* * Display */ if (my_args->m) { /* XXX fix me ! */ display_minimal_string(" "); } else { display("Call ID", (u_int8_t *) &hdr.call_id, 2, DISP_DEC); display("Result code", (u_int8_t *) &hdr.result_code, 1, DISP_DEC); display("Error code", (u_int8_t *) &hdr.error_code, 1, DISP_DEC); display("Cause code", (u_int8_t *) &hdr.cause_code, 2, DISP_DEC); display("Reserved", (u_int8_t *) &hdr.reserved, 2, DISP_DEC); display("Call statistics", (u_int8_t *) &hdr.call_stats, 128, DISP_HEX_MULTILINE); } } /*---------------------------------------------------------------------------- ** ** dump_pptp() ** ** Parse PPTP header and dump fields ** **---------------------------------------------------------------------------- */ void dump_pptp(packet_t *pkt) { pptp_generic_header_t pptp; /* char holder[64]; */ /* Set the layer */ set_layer(LAYER_APPLICATION); /* * Get the generic header */ if (get_packet_bytes((u_int8_t *) &pptp, pkt, sizeof(pptp_generic_header_t)) == 0) return; /* * Conversions */ pptp.length = ntohs(pptp.length); pptp.pptp_msg_type = ntohs(pptp.pptp_msg_type); pptp.cookie = ntohl(pptp.cookie); pptp.control_msg_type = ntohs(pptp.control_msg_type); pptp.reserved0 = ntohs(pptp.reserved0); /* * Minimal mode */ if (my_args->m) { display_minimal_string("| PPTP "); display_minimal_string(map2str(pptp_msgtype_map, pptp.pptp_msg_type)); display_minimal_string(" "); display_minimal_string(map2str(pptp_cntlmsgtype_map, pptp.control_msg_type)); display_minimal_string(" "); } else { /* announcement */ display_header_banner("PPTP Header"); /* dump common fields */ display("Length", (u_int8_t *) &pptp.length, 2, DISP_DEC); display_strmap("PPTP message type", pptp.pptp_msg_type, pptp_msgtype_map); display("Magic cookie", (u_int8_t *) &pptp.cookie, 4, DISP_HEX); display_strmap("Control message type", pptp.control_msg_type, pptp_cntlmsgtype_map); display("Reserved", (u_int8_t *) &pptp.reserved0, 2, DISP_HEX); } /* * Now decide what to do based on the control message type. * Note - management messages are currently undefined so we shouldn't * have to worry about them for a while. */ if (pptp.pptp_msg_type == PPTP_MSGTYPE_CONTROL) { switch(pptp.control_msg_type) { case PPTP_CNTLMSGTYPE_STARTCCREQ: dump_pptp_startccreq(pkt); break; case PPTP_CNTLMSGTYPE_STARTCCREP: dump_pptp_startccrep(pkt); break; case PPTP_CNTLMSGTYPE_OUTGOINGREQ: dump_pptp_outgoingreq(pkt); break; case PPTP_CNTLMSGTYPE_OUTGOINGREP: dump_pptp_outgoingrep(pkt); break; case PPTP_CNTLMSGTYPE_SETLINKINFO: dump_pptp_setlinkinfo(pkt); break; case PPTP_CNTLMSGTYPE_CALLCLEARREQ: dump_pptp_callclearreq(pkt); break; case PPTP_CNTLMSGTYPE_CALLDISCNTFY: dump_pptp_calldiscntfy(pkt); break; } } /* dump the hex buffer */ hexbuffer_flush(); return; }