Connection#

EtherNet/IP explicit-message connection support.

exception icspacket.proto.cip.connection.CIPProtocolError[source]#

Raised for malformed or failed EtherNet/IP/CIP exchanges.

class icspacket.proto.cip.connection.CIP_Connection(timeout: float = 10.0, *, sock: socket | None = None, sock_cls: Callable[[...], socket] | None = None, auto_register: bool = True)[source]#

Synchronous EtherNet/IP TCP connection for explicit CIP messaging.

property sock: socket#

Underlying TCP socket, or ConnectionNotEstablished if closed.

property session: int#

Current EtherNet/IP session handle.

connect(address: tuple[str, int]) None[source]#

Connect to an EtherNet/IP target and register a session, unless auto_register is disabled.

Parameters:

address (tuple[str, int]) – (host, port) of the EtherNet/IP target.

Raises:
close() None[source]#

Close the EtherNet/IP session and underlying TCP socket, best-effort.

Sends UnRegisterSession (See CIP Vol 2, clause 2-4.5) if a session is registered; failures are ignored since the socket is closed regardless.

register_session() int[source]#

Register an EtherNet/IP TCP session and return the target handle (See CIP Vol 2, clause 2-4.4).

unregister_session() None[source]#

Send UnRegisterSession (See CIP Vol 2, clause 2-4.5 - UnRegisterSession).

The target treats receipt of this command as its cue to close the TCP connection and never answers it, so this method just fires the request and returns without waiting for (or expecting) a reply.

send_data(octets: bytes, /) None[source]#

Send raw bytes directly on the underlying TCP socket.

Prefer send_rr_data()/send_unit_data() for framed CIP requests; this is the low-level primitive the base connection contract requires.

Parameters:

octets (bytes) – Raw bytes to send.

Raises:
recv_data() bytes[source]#

Receive one raw EtherNet/IP encapsulation packet.

Returns:

The header and payload bytes of one encapsulation packet.

Return type:

bytes

Raises:
send_rr_data(data: bytes | MessageRouterRequest) bytes[source]#

Send a UCMM request/reply packet via SendRRData.

send_unit_data(data: bytes | MessageRouterRequest, *, connected: bool = False, connection_id: int | None = None, sequence: int | None = None) bytes[source]#

Send connected data via SendUnitData and read the next peer packet.

SendUnitData is not a UCMM request/reply command; use send_rr_data() for unconnected Message Router traffic.

send_connected_unit_data(data: bytes | MessageRouterRequest, *, connection_id: int | None = None, sequence: int | None = None) bytes[source]#

Send Class-3 connected explicit data over SendUnitData.

list_identity() list[ListIdentityResponseItem][source]#

Return decoded ListIdentity response items (See CIP Vol 2, clause 2-4.2).

list_services() list[ListServicesResponseItem][source]#

Return decoded ListServices response items (See CIP Vol 2, clause 2-4.6).

list_interfaces() list[ListInterfacesResponseItem][source]#

Return known ListInterfaces response items (See CIP Vol 2, clause 2-4.3); Vol 2 defines none publicly.

generic_message(service: int | CommonService, path: EPATH | bytes | bytearray | Iterable[PortSegment | LogicalSegment | NetworkSegment | SymbolicSegment | DataSegment | ElectronicKeySegment], request_data: bytes = b'', *, connected: bool = False, return_response: bool = False) bytes | MessageRouterResponse[source]#

Send one Message Router request (See CIP Vol 1, clause A-3) and return its response data.

forward_open(request: ForwardOpenRequest | LargeForwardOpenRequest | None = None, **kwargs: Any) ForwardOpenResponse[source]#

Open a Class-3 or I/O connection through Connection Manager (See CIP Vol 1, clause 3-5.5.2).

large_forward_open(request: LargeForwardOpenRequest | None = None, **kwargs: Any) ForwardOpenResponse[source]#

Open a connection using the Large_Forward_Open service.

forward_close(request: ForwardCloseRequest | None = None, **kwargs: Any) ForwardCloseResponse[source]#

Close the current connection through Connection Manager (See CIP Vol 1, clause 3-5.5.3).

open_io_connection(response: ForwardOpenResponse | None = None, *, address: tuple[str, int] | None = None, timeout: float = 1.0, header_format: bool = True, sequence_format: bool = True) CIPIO_Connection[source]#

Open a Class 0/1 cyclic I/O (UDP) connection from a prior Forward_Open response.

response defaults to the result of the most recent forward_open()/large_forward_open() call on this connection. address defaults to the host this connection is registered against, using CIPIOConnection.DEFAULT_PORT (UDP/2222) unless overridden. header_format controls whether O->T datagrams carry the 4-byte Run/Idle header (required by exclusive-owner style connections; see icspacket.proto.cip.io). sequence_format controls whether O->T datagrams carry a 16-bit connected sequence count prefix; disable for targets that rely solely on the CPF-level sequence number instead.

send_io_data(data: bytes) None[source]#

Send one cyclic O->T datagram over the open Class 0/1 connection.

recv_io_data() bytes[source]#

Receive one cyclic T->O datagram over the open Class 0/1 connection.

close_io_connection() None[source]#

Close the Class 0/1 I/O connection opened by open_io_connection(), if any.

unconnected_send(message: MessageRouterRequest | bytes | None = None, route_path: EPATH | bytes | Iterable[Any] = <EPATH []>, *, priority: int = 0, timeout_ticks: int = 0, request: UnconnectedSendRequest | None = None) MessageRouterResponse[source]#

Route a Message Router request through Connection Manager (See CIP Vol 1, clause 3-5.5.4).

object_path(class_code: int | ClassCode, instance: int, attribute: int | None = None) EPATH[source]#

Build the EPATH addressing a class/instance, optionally down to one attribute.

Parameters:
  • class_code – The CIP object class code.

  • instance – The target object instance.

  • attribute – Narrows the path to one specific attribute, if given.

get_attribute_single(class_code: int | ClassCode, instance: int, attribute: int) bytes[source]#

Read one attribute using Get_Attribute_Single (See CIP Vol 1, clause A-3).

set_attribute_single(class_code: int | ClassCode, instance: int, attribute: int, value: bytes) bytes[source]#

Write one attribute using Set_Attribute_Single (See CIP Vol 1, clause A-3).

get_attributes_all(class_code: int | ClassCode, instance: int) bytes[source]#

Read all attributes from a class instance using Get_Attributes_All (See CIP Vol 1, clause A-3).

CIP status, service, and object-class constants.

Collects the general status codes (See CIP Volume 1, Appendix B, clause B-1, Table B-1.1 - CIP General Status Codes), the common service codes (See CIP Volume 1, Appendix A, clause A-3 - CIP Common Services), and the object-class codes (See CIP Volume 1, clause 4-3 - Class Code) that protocol implementations need.

exception icspacket.proto.cip.const.CIPStatusError(general_status: GeneralStatus | int, additional_status: tuple[int, ...] | list[int] = (), *, service: int | IntEnum | None = None, class_code: int | IntEnum | None = None, instance: int | None = None, message: str | None = None)[source]#

Exception raised when a CIP service response reports failure.

additional_status contains the UINT16 words following the general status byte in a reply. Context fields are optional because a decoder often sees the status before it has resolved the request path.

property status_name: str#

Human-readable name for the general status value.

class icspacket.proto.cip.const.ClassCode(*values)[source]#

Object class codes (See CIP Volume 1, clause 4-3 - Class Code, and Volume 1, Table 5-1.1 - Object Specifications in the CIP Object Library).

DLR through PRP_NODES_TABLE are EtherNet/IP-specific object classes (See CIP Volume 2, clauses 5-6 through 5-14); TCP_IP_INTERFACE and ETHERNET_LINK likewise (See CIP Volume 2, clauses 5-4 and 5-5). Every other member is defined in CIP Volume 1.

DEVICE_NET = 3#

DeviceNet Object (See CIP Volume 1, clause 5-4; fully specified in CIP Volume 3, DeviceNet Adaptation of CIP).

DLR = 71#

Device Level Ring Object (See CIP Volume 2, clause 5-6).

QOS = 72#

QoS Object (See CIP Volume 2, clause 5-7).

BASE_SWITCH = 81#

Base Switch Object (See CIP Volume 2, clause 5-8).

SNMP = 82#

Simple Network Management (SNMP) Object (See CIP Volume 2, clause 5-9).

POWER_MANAGEMENT = 83#

Power Management Object (See CIP Volume 2, clause 5-10).

RSTP_BRIDGE = 84#

RSTP Bridge Object (See CIP Volume 2, clause 5-11).

RSTP_PORT = 85#

RSTP Port Object (See CIP Volume 2, clause 5-12).

PRP = 86#

Parallel Redundancy Protocol (PRP) Object (See CIP Volume 2, clause 5-13).

PRP_NODES_TABLE = 87#

PRP Nodes Table Object (See CIP Volume 2, clause 5-14).

CONNECTION_CONFIGURATION = 243#

Connection Configuration Object (See CIP Volume 1, clause 5-48).

PORT = 244#

Port object (See CIP Volume 1, clause 3-7).

class icspacket.proto.cip.const.CommonService(*values)[source]#

Common service codes (See CIP Volume 1, clause A-3 - CIP Common Services), plus the Connection Manager object’s own service codes (See CIP Volume 1, clause 3-5.5).

class icspacket.proto.cip.const.GeneralStatus(*values)[source]#

General status codes (See CIP Volume 1, clause B-1, Table B-1.1).