/****************************************************************************
** 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;
}
syntax highlighted by Code2HTML, v. 0.9.1