Skip to content
Snippets Groups Projects
Commit 5c4c4175 authored by Jan Sebechlebsky's avatar Jan Sebechlebsky
Browse files

Add support for PPTP Control Connection protocol

parent d79c849e
No related branches found
No related tags found
No related merge requests found
......@@ -391,7 +391,7 @@ contribs: a dict which can be used by contrib layers to store local configuratio
geoip_city_ipv6 = '/usr/share/GeoIP/GeoIPCityv6.dat'
load_layers = ["l2", "inet", "dhcp", "dns", "dot11", "gprs", "tls",
"hsrp", "inet6", "ir", "isakmp", "l2tp", "mgcp",
"mobileip", "netbios", "netflow", "ntp", "ppp",
"mobileip", "netbios", "netflow", "ntp", "ppp", "pptp",
"radius", "rip", "rtp", "skinny", "smb", "snmp",
"tftp", "x509", "bluetooth", "dhcp6", "llmnr",
"sctp", "vrrp", "ipsec", "lltd", "vxlan"]
......
## This file is part of Scapy
## See http://www.secdev.org/projects/scapy for more informations
## Copyright (C) Jan Sebechlebsky <sebechlebskyjan@gmail.com>
## This program is published under a GPLv2 license
"""
PPTP (Point to Point Tunneling Protocol)
[RFC 2637]
"""
from scapy.packet import Packet, bind_layers
from scapy.layers.inet import TCP
from scapy.fields import ByteEnumField, FieldLenField, FlagsField, IntField, IntEnumField,\
LenField, XIntField, ShortField, ShortEnumField, StrFixedLenField,\
StrLenField, XShortField, XByteField
_PPTP_MAGIC_COOKIE = 0x1a2b3c4d
_PPTP_msg_type = {1: "Control Message",
2: "Managemenent Message"}
_PPTP_ctrl_msg_type = { # Control Connection Management
1: "Start-Control-Connection-Request",
2: "Start-Control-Connection-Reply",
3: "Stop-Control-Connection-Request",
4: "Stop-Control-Connection-Reply",
5: "Echo-Request",
6: "Echo-Reply",
# Call Management
7: "Outgoing-Call-Request",
8: "Outgoing-Call-Reply",
9: "Incoming-Call-Request",
10: "Incoming-Call-Reply",
11: "Incoming-Call-Connected",
12: "Call-Clear-Request",
13: "Call-Disconnect-Notify",
# Error Reporting
14: "WAN-Error-Notify",
# PPP Session Control
15: "Set-Link-Info"}
_PPTP_general_error_code = {0: "None",
1: "Not-Connected",
2: "Bad-Format",
3: "Bad-Value",
4: "No-Resource",
5: "Bad-Call ID",
6: "PAC-Error"}
class PPTP(Packet):
name = "PPTP"
fields_desc = [FieldLenField("len", None, fmt="H", length_of="data",
adjust=lambda p, x: x + 12),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 1, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
StrLenField("data", "",length_from=lambda p: p.len - 12)]
registered_options = {}
@classmethod
def register_variant(cls):
cls.registered_options[cls.ctrl_msg_type.default] = cls
@classmethod
def dispatch_hook(cls, _pkt=None, *args, **kargs):
if _pkt:
o = ord(_pkt[9])
return cls.registered_options.get(o, cls)
return cls
_PPTP_FRAMING_CAPABILITIES_FLAGS = ["Asynchronous Framing supported",
"Synchronous Framing supported"]
_PPTP_BEARER_CAPABILITIES_FLAGS = ["Analog access supported",
"Digital access supported"]
class PPTPStartControlConnectionRequest(PPTP):
name = "PPTP Start Control Connection Request"
fields_desc = [LenField("len", 156),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 1, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("protocol_version", 1),
XShortField("reserved_1", 0x0000),
FlagsField("framing_capabilities", 0, 32,
_PPTP_FRAMING_CAPABILITIES_FLAGS),
FlagsField("bearer_capabilities", 0, 32,
_PPTP_BEARER_CAPABILITIES_FLAGS),
ShortField("maximum_channels", 65535),
ShortField("firmware_revision", 256),
StrFixedLenField("host_name", "linux", 64),
StrFixedLenField("vendor_string", "", 64)]
_PPTP_start_control_connection_result = {1: "OK",
2: "General error",
3: "Command channel already exists",
4: "Not authorized",
5: "Unsupported protocol version"}
class PPTPStartControlConnectionReply(PPTP):
name = "PPTP Start Control Connection Reply"
fields_desc = [LenField("len", 156),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 2, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("protocol_version", 1),
ByteEnumField("result_code", 1,
_PPTP_start_control_connection_result),
ByteEnumField("error_code", 0, _PPTP_general_error_code),
FlagsField("framing_capabilities", 0, 32,
_PPTP_FRAMING_CAPABILITIES_FLAGS),
FlagsField("bearer_capabilities", 0, 32,
_PPTP_BEARER_CAPABILITIES_FLAGS),
ShortField("maximum_channels", 65535),
ShortField("firmware_revision", 256),
StrFixedLenField("host_name", "linux", 64),
StrFixedLenField("vendor_string", "", 64)]
def answers(self, other):
return isinstance(other, PPTPStartControlConnectionRequest)
_PPTP_stop_control_connection_reason = {1: "None",
2: "Stop-Protocol",
3: "Stop-Local-Shutdown"}
class PPTPStopControlConnectionRequest(PPTP):
name = "PPTP Stop Control Connection Request"
fields_desc = [LenField("len", 16),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 3, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ByteEnumField("reason", 1,
_PPTP_stop_control_connection_reason),
XByteField("reserved_1", 0x00),
XShortField("reserved_2", 0x0000)]
_PPTP_stop_control_connection_result = {1: "OK",
2: "General error"}
class PPTPStopControlConnectionReply(PPTP):
name = "PPTP Stop Control Connection Reply"
fields_desc = [LenField("len", 16),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 4, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ByteEnumField("result_code", 1,
_PPTP_stop_control_connection_result),
ByteEnumField("error_code", 0, _PPTP_general_error_code),
XShortField("reserved_2", 0x0000)]
def answers(self, other):
return isinstance(other, PPTPStopControlConnectionRequest)
class PPTPEchoRequest(PPTP):
name = "PPTP Echo Request"
fields_desc = [LenField("len", 16),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 5, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
IntField("identifier", None)]
_PPTP_echo_result = {1: "OK",
2: "General error"}
class PPTPEchoReply(PPTP):
name = "PPTP Echo Reply"
fields_desc = [LenField("len", 20),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 6, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
IntField("identifier", None),
ByteEnumField("result_code", 1, _PPTP_echo_result),
ByteEnumField("error_code", 0, _PPTP_general_error_code),
XShortField("reserved_1", 0x0000)]
def answers(self, other):
return isinstance(other, PPTPEchoRequest) and other.identifier == self.identifier
_PPTP_bearer_type = {1: "Analog channel",
2: "Digital channel",
3: "Any type of channel"}
_PPTP_framing_type = {1: "Asynchronous framing",
2: "Synchronous framing",
3: "Any type of framing"}
class PPTPOutgoingCallRequest(PPTP):
name = "PPTP Outgoing Call Request"
fields_desc = [LenField("len", 168),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 7, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("call_id", 1),
ShortField("call_serial_number", 0),
IntField("minimum_bps", 32768),
IntField("maximum_bps", 2147483648),
IntEnumField("bearer_type", 3, _PPTP_bearer_type),
IntEnumField("framing_type", 3, _PPTP_framing_type),
ShortField("pkt_window_size", 16),
ShortField("pkt_proc_delay", 0),
ShortField('phone_number_len', 0),
XShortField("reserved_1", 0x0000),
StrFixedLenField("phone_number", '', 64),
StrFixedLenField("subaddress", '', 64)]
_PPTP_result_code = {1: "Connected",
2: "General error",
3: "No Carrier",
4: "Busy",
5: "No dial tone",
6: "Time-out",
7: "Do not accept"}
class PPTPOutgoingCallReply(PPTP):
name = "PPTP Outgoing Call Reply"
fields_desc = [LenField("len", 32),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 8, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("call_id", 1),
ShortField("peer_call_id", 1),
ByteEnumField("result_code", 1, _PPTP_result_code),
ByteEnumField("error_code", 0, _PPTP_general_error_code),
ShortField("cause_code", 0),
IntField("connect_speed", 100000000),
ShortField("pkt_window_size", 16),
ShortField("pkt_proc_delay", 0),
IntField("channel_id", 0)]
def answers(self, other):
return isinstance(other, PPTPOutgoingCallRequest) and other.call_id == self.peer_call_id
class PPTPIncomingCallRequest(PPTP):
name = "PPTP Incoming Call Request"
fields_desc = [LenField("len", 220),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 9, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("call_id", 1),
ShortField("call_serial_number", 1),
IntEnumField("bearer_type", 3, _PPTP_bearer_type),
IntField("channel_id", 0),
ShortField("dialed_number_len", 0),
ShortField("dialing_number_len", 0),
StrFixedLenField("dialed_number", "", 64),
StrFixedLenField("dialing_number", "", 64),
StrFixedLenField("subaddress", "", 64)]
class PPTPIncomingCallReply(PPTP):
name = "PPTP Incoming Call Reply"
fields_desc = [LenField("len", 148),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 10, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("call_id", 1),
ShortField("peer_call_id", 1),
ByteEnumField("result_code", 1, _PPTP_result_code),
ByteEnumField("error_code", 0, _PPTP_general_error_code),
ShortField("pkt_window_size", 64),
ShortField("pkt_transmit_delay", 0),
XShortField("reserved_1", 0x0000)]
def answers(self, other):
return isinstance(other, PPTPIncomingCallRequest) and other.call_id == self.peer_call_id
class PPTPIncomingCallConnected(PPTP):
name = "PPTP Incoming Call Connected"
fields_desc = [LenField("len", 28),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 11, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("peer_call_id", 1),
XShortField("reserved_1", 0x0000),
IntField("connect_speed", 100000000),
ShortField("pkt_window_size", 64),
ShortField("pkt_transmit_delay", 0),
IntEnumField("framing_type", 1, _PPTP_framing_type)]
def answers(self, other):
return isinstance(other, PPTPIncomingCallReply) and other.call_id == self.peer_call_id
class PPTPCallClearRequest(PPTP):
name = "PPTP Call Clear Request"
fields_desc = [LenField("len", 16),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 12, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("call_id", 1),
XShortField("reserved_1", 0x0000)]
_PPTP_call_disconnect_result = {1: "Lost Carrier",
2: "General error",
3: "Admin Shutdown",
4: "Request"}
class PPTPCallDisconnectNotify(PPTP):
name = "PPTP Call Disconnect Notify"
fields_desc = [LenField("len", 148),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 13, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("call_id", 1),
ByteEnumField("result_code", 1,
_PPTP_call_disconnect_result),
ByteEnumField("error_code", 0, _PPTP_general_error_code),
ShortField("cause_code", 0),
XShortField("reserved_1", 0x0000),
StrFixedLenField("call_statistic", "", 128)]
class PPTPWANErrorNotify(PPTP):
name = "PPTP WAN Error Notify"
fields_desc = [LenField("len", 40),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 14, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("peer_call_id", 1),
XShortField("reserved_1", 0x0000),
IntField("crc_errors", 0),
IntField("framing_errors", 0),
IntField("hardware_overruns", 0),
IntField("buffer_overruns", 0),
IntField("time_out_errors", 0),
IntField("alignment_errors", 0)]
class PPTPSetLinkInfo(PPTP):
name = "PPTP Set Link Info"
fields_desc = [LenField("len", 24),
ShortEnumField("type", 1, _PPTP_msg_type),
XIntField("magic_cookie", _PPTP_MAGIC_COOKIE),
ShortEnumField("ctrl_msg_type", 15, _PPTP_ctrl_msg_type),
XShortField("reserved_0", 0x0000),
ShortField("peer_call_id", 1),
XShortField("reserved_1", 0x0000),
XIntField("send_accm", 0x00000000),
XIntField("receive_accm", 0x00000000)]
bind_layers(TCP, PPTP, sport=1723)
bind_layers(TCP, PPTP, dport=1723)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment