pysap.SAPRouter module

exception pysap.SAPRouter.SAPRouteException[source]

Bases: exceptions.Exception

Exception for SAP Router routing errors

class pysap.SAPRouter.SAPRoutedStreamSocket(sock, route, talk_mode=None, router_version=None, keep_alive=True, base_cls=None)[source]

Bases: pysap.SAPNI.SAPNIStreamSocket

Stream socket implementation for a connection routed through a SAP Router server. It works by wrapping a SAPNIStreamSocket and connecting first to the SAP Router given a route string or list of SAPRouterRouteHop.

desc = 'NI Stream socket routed trough a SAP Router'
classmethod get_nisocket(host=None, port=None, route=None, password=None, talk_mode=None, router_version=None, **kwargs)[source]

Helper function to obtain a SAPRoutedStreamSocket. If no route is specified, it returns a plain SAPNIStreamSocket. If no route is specified and the talk mode is raw, it returns a plain StreamSocket as it’s assumed that the NI layer is not desired.

Parameters:
  • host (C{string}) – target host to connect to if not specified in the route
  • port (int) – target port to connect to if not specified in the route
  • route (C{string} or list of SAPRouterRouteHop) – route to use for determining the SAP Router to connect
  • password (C{string}) – target password if not specified in the route
  • talk_mode (int) – the talk mode to use for requesting the route
  • router_version (int) – the router version to use for requesting the route
  • kwargs – arguments to pass to SAPRoutedStreamSocket constructor
Returns:

connected socket through the specified route

Return type:

SAPRoutedStreamSocket

Raises:
  • SAPRouteException – if the route request to the target host/port was not accepted by the SAP Router
  • socket.error – if the connection to the target host/port failed or the SAP Router returned an error
recv()[source]

Receive a packet from the target host. If the talk mode in use is native and we’ve already set the route, the packet received is a raw packet. Otherwise, the packet received is a NI layer packet in the same way the SAPNIStreamSocket works.

route_to(route, talk_mode)[source]

Make the route request to the target host/service.

Parameters:
  • route (list of SAPRouterRouteHop) – a route to specify to the SAP Router
  • talk_mode (int) – the talk mode to use when routing
Raises:
  • SAPRouteException – if the route request to the target host/port was not accepted by the SAP Router
  • socket.error – if the connection to the target host/port failed or the SAP Router returned an error
send(packet)[source]

Send a packet. If the talk mode in use is native the packet sent is a raw packet. Otherwise, the packet is a NI layer packet in the same way the SAPNIStreamSocket works.

Parameters:packet (Packet) – packet to send
class pysap.SAPRouter.SAPRouter(_pkt='', post_transform=None, _internal=0, _underlayer=None, **fields)[source]

Bases: scapy.packet.Packet

SAP Router packet

This packet is used for general SAP Router packets. There are (at least) five types of SAP Router packets:

1. Route packets. For requesting the routing of a connection to a remote hosts. The packet contains some general information and a connection string with a list of routing hops (SAPRouterRouteHop).

2. Administration packets. This packet is used for the SAP Router to send administrative commands. It’s suppose to be used only from the hosts running the SAP Router or when an specific route is included in the routing table. Generally administration packets are not accepted from the external binding.

  1. Error Information packets. Packets sent when an error occurred.

4. Control Message packets. Used to perform some control activities, like retrieving the current SAPRouter version or to perform the SNC handshake. They have the same structure that error information packets.

5. Route accepted packet. Used to acknowledge a route request (“NI_PONG”).

Routed packets and some responses doesn’t fill in these five packet types. For identifying those cases, you should check the type using the function router_is_known_type.

NI Versions found (unconfirmed):
  • 30: Release 40C
  • 36: Release <6.20
  • 38: Release 7.00/7.10
  • 39: Release 7.11
  • 40: Release 7.20/7.21
SAPROUTER_ADMIN = 'ROUTER_ADM'
Cvar:Constant for administration packets
Type:C{string}
SAPROUTER_CONTROL = 'NI_RTERR'
Cvar:Constant for control messages packets
Type:C{string}
SAPROUTER_DEFAULT_VERSION = 40
SAPROUTER_ERROR = 'NI_RTERR'
Cvar:Constant for error information packets
Type:C{string}
SAPROUTER_PONG = 'NI_PONG'
Cvar:Constant for route accepted packets
Type:C{string}
SAPROUTER_ROUTE = 'NI_ROUTE'
Cvar:Constant for route packets
Type:C{string}
aliastypes = [<class 'pysap.SAPRouter.SAPRouter'>, <class 'scapy.packet.Packet'>]
fields_desc = [<Field (SAPRouter).type>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>, <scapy.fields.ConditionalField object>]
router_type_values = ['ROUTER_ADM', 'NI_RTERR', 'NI_RTERR', 'NI_ROUTE', 'NI_PONG']
Cvar:List of known packet types
Type:list of C{string}
class pysap.SAPRouter.SAPRouterError(_pkt='', post_transform=None, _internal=0, _underlayer=None, **fields)[source]

Bases: pysap.utils.fields.PacketNoPadded

SAP Router Protocol Error Text

This packet is used to describe an error returned by SAP Router.

aliastypes = [<class 'pysap.SAPRouter.SAPRouterError'>, <class 'pysap.utils.fields.PacketNoPadded'>, <class 'scapy.packet.Packet'>]
fields_desc = [<Field (SAPRouterError).eyecatcher>, <Field (SAPRouterError).counter>, <Field (SAPRouterError).error>, <Field (SAPRouterError).return_code>, <Field (SAPRouterError).component>, <Field (SAPRouterError).release>, <Field (SAPRouterError).version>, <Field (SAPRouterError).module>, <Field (SAPRouterError).line>, <Field (SAPRouterError).detail>, <Field (SAPRouterError).error_time>, <Field (SAPRouterError).system_call>, <Field (SAPRouterError).errorno>, <Field (SAPRouterError).errorno_text>, <Field (SAPRouterError).error_count>, <Field (SAPRouterError).location>, <Field (SAPRouterError).XXX5>, <Field (SAPRouterError).XXX6>, <Field (SAPRouterError).XXX7>, <Field (SAPRouterError).XXX8>, <Field (SAPRouterError).eyecatcher>]
time_format = '%a %b %d %H:%M:%S %Y'
Cvar:Format to use when building the time field
Type:C{string}
class pysap.SAPRouter.SAPRouterInfoClient(_pkt='', post_transform=None, _internal=0, _underlayer=None, **fields)[source]

Bases: pysap.utils.fields.PacketNoPadded

SAP Router Protocol Information Request Client info

This packet is used to return the information of a connected client.

aliastypes = [<class 'pysap.SAPRouter.SAPRouterInfoClient'>, <class 'pysap.utils.fields.PacketNoPadded'>, <class 'scapy.packet.Packet'>]
fields_desc = [<Field (SAPRouterInfoClient).id>, <Field (SAPRouterInfoClient).flag_XXX1>, <Field (SAPRouterInfoClient).flag_XXX2>, <Field (SAPRouterInfoClient).flag_XXX3>, <Field (SAPRouterInfoClient).flag_XXX4>, <Field (SAPRouterInfoClient).flag_XXX5>, <Field (SAPRouterInfoClient).flag_traced>, <Field (SAPRouterInfoClient).flag_connected>, <Field (SAPRouterInfoClient).flag_routed>, <Field (SAPRouterInfoClient).connected_on>, <Field (SAPRouterInfoClient).address>, <Field (SAPRouterInfoClient).partner>, <Field (SAPRouterInfoClient).service>, <Field (SAPRouterInfoClient).XXX3>]
class pysap.SAPRouter.SAPRouterInfoClients(_pkt='', post_transform=None, _internal=0, _underlayer=None, **fields)[source]

Bases: pysap.utils.fields.PacketNoPadded

SAP Router Protocol Information Request Client info list

This packet is used to return the list of current connected clients.

aliastypes = [<class 'pysap.SAPRouter.SAPRouterInfoClients'>, <class 'pysap.utils.fields.PacketNoPadded'>, <class 'scapy.packet.Packet'>]
fields_desc = [<Field (SAPRouterInfoClients).clients>]
class pysap.SAPRouter.SAPRouterInfoServer(_pkt='', post_transform=None, _internal=0, _underlayer=None, **fields)[source]

Bases: pysap.utils.fields.PacketNoPadded

SAP Router Protocol Information Request Server info

This packet is used to return information about the SAP Router

aliastypes = [<class 'pysap.SAPRouter.SAPRouterInfoServer'>, <class 'pysap.utils.fields.PacketNoPadded'>, <class 'scapy.packet.Packet'>]
fields_desc = [<Field (SAPRouterInfoServer).pid>, <Field (SAPRouterInfoServer).ppid>, <Field (SAPRouterInfoServer).started_on>, <Field (SAPRouterInfoServer).port>, <Field (SAPRouterInfoServer).pport>]
class pysap.SAPRouter.SAPRouterNativeProxy(bind_address, bind_port, remote_address, remote_port, handler, target_address, target_port, target_pass=None, talk_mode=0, backlog=5, keep_alive=True, options=None)[source]

Bases: pysap.SAPNI.SAPNIProxy

SAP Router Native Proxy

Proxy implementation that routes traffic through a remote SAP Router server to a target host/port. It works by binding a SAPNIStreamSocket and requesting the SAP Router a route to the target location. If the route is accepted it keeps the listener open for connections and spawn a new SAPRouterNativeRouterHandler instance for each client.

Example usage:

proxy = SAPRouterNativeProxy(local_host, local_port,
                             remote_host, remote_port,
                             SAPRouterNativeRouterHandler,
                             target_address=target_address,
                             target_post=target_port,
                             target_pass=target_pass)
proxy.handle_connection()
handle_connection()[source]

Block until a connection is received from the listener, request a route to forward the traffic through the remote SAP Router and handle the client using the provided handler class.

Returns:the handler instance handling the request
Return type:SAPNIProxyHandler
route()[source]

Requests a route to forward the traffic through the remote SAP Router.

Raises:
  • SAPRouteException – if the route request is denied
  • Exception – if an error occurred when requesting the route
class pysap.SAPRouter.SAPRouterNativeRouterHandler(client, server, options=None)[source]

Bases: pysap.SAPNI.SAPNIProxyHandler

SAP Router Native Proxy Handler

Handles packets routed through a remote SAP Router. It works by bypassing the SAP NI layer in order to allow native traffic.

recv_send(local, remote, process)[source]

Receives data from one socket connection, process it and send to the remote connection.

Parameters:
  • local (SAPNIStreamSocket) – the local socket
  • remote (SAPNIStreamSocket) – the remote socket
  • process (function) – the function that process the incoming data
class pysap.SAPRouter.SAPRouterRouteHop(_pkt='', post_transform=None, _internal=0, _underlayer=None, **fields)[source]

Bases: pysap.utils.fields.PacketNoPadded

SAP Router Protocol Route Hop

This packet is used to describe a hop in a route using the SAP Router.

aliastypes = [<class 'pysap.SAPRouter.SAPRouterRouteHop'>, <class 'pysap.utils.fields.PacketNoPadded'>, <class 'scapy.packet.Packet'>]
fields_desc = [<Field (SAPRouterRouteHop).hostname>, <Field (SAPRouterRouteHop).port>, <Field (SAPRouterRouteHop).password>]
classmethod from_hops(route_hops)[source]

Build a route string from a list of route hops.

Parameters:route_hops (list of SAPRouterRouteHop) – route hops
Returns:route string
Return type:C{string}
classmethod from_string(route_string)[source]

Build a list of route hops from a route string. The format of a route string is:

(/H/host/S/service/W/pass)*

or for older versions (<4.0):

(/H/host/S/service/P/pass)*

Parameters:route_string (C{string}) – route string
Returns:route hops in the route string
Return type:list of SAPRouterRouteHop
regex = <_sre.SRE_Pattern object>
Cvar:Regular expression for matching route strings
Type:regex
pysap.SAPRouter.get_router_version(connection)[source]

Helper function to retrieve the version of a remote SAP Router. It uses a control packet with the ‘version request’ operation code. The version is obtained either from a valid ‘version response’ packet or from the error message packet if something happened.

Parameters:connection (SAPNIStreamSocket) – connection with the SAP Router
Returns:version
pysap.SAPRouter.router_adm_commands = {2: 'Information Request', 3: 'New Route Table Request', 4: 'Toggle Trace Request', 5: 'Stop Request', 6: 'Cancel Route Request', 7: 'Dump Buffers Request', 8: 'Flush Buffers Request', 9: 'Soft Shutdown Request', 10: 'Set Trace Peer', 11: 'Clear Trace Peer', 12: 'Trace Connection', 13: 'Trace Connection', 14: 'Hide Error Information Request'}

Router Administration Command values

pysap.SAPRouter.router_control_opcodes = {0: 'Error information', 1: 'Version request', 2: 'Version response', 5: 'Send Handle (5)', 6: 'Send Handle (6)', 8: 'Send Handle (8)', 70: 'SNC request', 71: 'SNC handshake complete'}

Router Opcode values

pysap.SAPRouter.router_is_admin(pkt)[source]

Returns if the packet is a Admin packet.

Parameters:pkt (SAPRouter) – packet to look at
Returns:if the type of the packet is Admin
Return type:bool
pysap.SAPRouter.router_is_control(pkt)[source]

Returns if the packet is a Control packet.

Parameters:pkt (SAPRouter) – packet to look at
Returns:if the type of the packet is Control
Return type:bool
pysap.SAPRouter.router_is_error(pkt)[source]

Returns if the packet is a Error Information packet.

Parameters:pkt (SAPRouter) – packet to look at
Returns:if the type of the packet is Error
Return type:bool
pysap.SAPRouter.router_is_known_type(pkt)[source]

Returns if the packet is of a known type (Admin, Route, Error or Pong).

Parameters:pkt (SAPRouter) – packet to look at
Returns:if the type of the packet is known
Return type:bool
pysap.SAPRouter.router_is_pong(pkt)[source]

Returns if the packet is a Pong (route accepted) packet.

Parameters:pkt (SAPRouter) – packet to look at
Returns:if the type of the packet is Pong
Return type:bool
pysap.SAPRouter.router_is_route(pkt)[source]

Returns if the packet is a Route packet.

Parameters:pkt (SAPRouter) – packet to look at
Returns:if the type of the packet is Route
Return type:bool
pysap.SAPRouter.router_ni_talk_mode_values = {0: 'NI_MSG_IO', 1: 'NI_RAW_IO', 2: 'NI_ROUT_IO'}

Router NI Talk mode values

pysap.SAPRouter.router_return_codes = {-104: 'Error in the SNC shift (NIEROUT_SNC_FAILURE)', -103: 'Error in external library (NIEROUT_EXTERN)', -102: 'Client not available (NIEROUT_NOCLIENT)', -101: 'Talkmode not allowed (NIEROUT_MODE_DENIED)', -100: 'Max. number of clients reached (NIEROUT_OVERFLOW)', -99: 'Information request refused (NIEROUT_INFO_DENIED)', -98: 'saprouter shutdown (NIEROUT_SHUTDOWN)', -97: 'Connection cancelled by administrator (NIEROUT_CANCELED)', -96: 'Invalid client version (NIEROUT_VERSION)', -95: 'Connection terminated (NIEROUT_CONN_BROKEN)', -94: 'Connect from source to destination not allowed (NIEROUT_PERM_DENIED)', -93: 'NI-internal errors (NIEROUT_INTERN)', -92: 'Connection setup failed (NIEROUT_CONN_REFUSED)', -91: 'Service unknown (NIEROUT_SERV_UNKNOWN)', -90: 'Host name unknown (NIEROUT_HOST_UNKNOWN)', -20: 'Requested package too large (NIETOO_BIG)', -19: 'queue limit reached, next package not accepted (NIEQUE_FULL)', -18: 'Opcode received (NIEOPCODE)', -17: 'Error in the SNC shift in the saprouter ==> (NIESNC_FAILURE)', -16: 'Local hostname invalid (NIEMYHOST_VERIFY)', -15: 'No free port in range (NIENOFREEPORT)', -14: 'Local hostname cannot be found (NIEMYHOSTNAME)', -13: 'Invalid version (NIEVERSION)', -12: 'Connection to partner via NiRouter not yet set up (NIECONN_PENDING)', -11: 'PING/PONG signal received (NIEPING)', -10: 'Connection setup failed (NIECONN_REFUSED)', -9: 'Wake-Up (without data) (NIEWAKEUP)', -8: 'Invalid parameters (NIEINVAL)', -7: 'Data range too small (NIETOO_SMALL)', -6: 'Connection to partner broken (NIECONN_BROKEN)', -5: 'Time limit reached (NIETIMEOUT)', -4: 'Service already used (NIESERV_USED)', -3: 'Service unknown (NIESERV_UNKNOWN)', -2: 'Host name unknown (NIEHOST_UNKNOWN)', -1: 'NI-internal error (NIEINTERN)'}

Router Return Code values