{"id":13627469,"url":"https://github.com/scy-phy/scapy-cip-enip","last_synced_at":"2026-04-06T07:35:10.549Z","repository":{"id":36216624,"uuid":"40520903","full_name":"scy-phy/scapy-cip-enip","owner":"scy-phy","description":"EtherNet/IP+CIP dissector for Scapy","archived":false,"fork":false,"pushed_at":"2017-02-14T19:01:29.000Z","size":25,"stargazers_count":95,"open_issues_count":4,"forks_count":41,"subscribers_count":19,"default_branch":"master","last_synced_at":"2025-05-23T15:02:53.478Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/scy-phy.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-08-11T04:14:19.000Z","updated_at":"2025-05-09T20:13:35.000Z","dependencies_parsed_at":"2022-07-29T21:09:43.589Z","dependency_job_id":null,"html_url":"https://github.com/scy-phy/scapy-cip-enip","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/scy-phy/scapy-cip-enip","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scy-phy%2Fscapy-cip-enip","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scy-phy%2Fscapy-cip-enip/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scy-phy%2Fscapy-cip-enip/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scy-phy%2Fscapy-cip-enip/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/scy-phy","download_url":"https://codeload.github.com/scy-phy/scapy-cip-enip/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/scy-phy%2Fscapy-cip-enip/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31463160,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T22:00:34.400Z","updated_at":"2026-04-06T07:35:10.533Z","avatar_url":"https://github.com/scy-phy.png","language":"Python","funding_links":[],"categories":["Ethernet/IP","\u003ca id=\"01f99d208e245eb44f15f720043b50d4\"\u003e\u003c/a\u003eScapy"],"sub_categories":["Tools"],"readme":"================================\nEthernet/IP dissectors for Scapy\n================================\n\nThis repository contains a Python library which can be used to interact with components of a network using ENIP (Ethernet/IP) and CIP (Common Industrial Protocol) protocols.\nIt uses scapy (http://www.secdev.org/projects/scapy/) to implement packet dissectors which are able to decode a part of the network traffic.\nThese dissectors can also be used to craft packets, which allows directly communicating with the PLCs (Programmable Logic Controllers) of the network.\n\nThis project has been created to help analyzing the behavior of SWaT, a water treatment testbed built at SUTD (Singapore University of Technology and Design). For more information on our work, visit http://scy-phy.net\n\nTherefore, it mostly implements a subset of CIP specification, which is used in this system.\n\n\nRequirements\n============\n\n* Python 2.7\n* Scapy (http://www.secdev.org/projects/scapy/)\n\n\nExample of packet decoding\n==========================\n\nHere is the raw content of a packet sent to a PLC to query a tag (in SWaT), as seen by an hexadecimal viewer::\n\n    00000000: 801d 9cc8 bde7 001d 9cc6 72e8 0800 4500  ..........r...E.\n    00000010: 005e 2f95 4000 8006 4746 c0a8 0164 c0a8  .^/.@...GF...d..\n    00000020: 010a c203 af12 8e7a 4387 01bd 1e5e 5018  .......zC....^P.\n    00000030: 829c 2a07 0000 7000 1e00 0200 1600 0000  ..*...p.........\n    00000040: 0000 0000 0000 0000 0000 0000 0000 0000  ................\n    00000050: 0000 0000 0200 a100 0400 2042 b5ff b100  .......... B....\n    00000060: 0a00 8a07 4c03 20b2 2500 2200            ....L. .%.\".\n\nThis packet can be decoded using this Python script:\n\n.. code-block:: python\n\n    #!/usr/bin/env python2\n    import binascii\n    from scapy.all import *\n    import cip\n\n    rawpkt = binascii.unhexlify(\n        '801d9cc8bde7001d9cc672e808004500005e2f95400080064746c0a80164'\n        'c0a8010ac203af128e7a438701bd1e5e5018829c2a07000070001e000200'\n        '1600000000000000000000000000000000000000000000000200a1000400'\n        '2042b5ffb1000a008a074c0320b225002200')\n    pkt = Ether(rawpkt)\n    pkt.show()\n\nThis script prints the structure of the packet with every protocol layer (Ethernet, IP, ENIP and CIP)::\n\n    ###[ Ethernet ]###\n      dst       = 00:1d:9c:c8:bd:e7\n      src       = 00:1d:9c:c6:72:e8\n      type      = 0x800\n    ###[ IP ]###\n         version   = 4L\n         ihl       = 5L\n         tos       = 0x0\n         len       = 94\n         id        = 12181\n         flags     = DF\n         frag      = 0L\n         ttl       = 128\n         proto     = tcp\n         chksum    = 0x4746\n         src       = 192.168.1.100\n         dst       = 192.168.1.10\n         \\options   \\\n    ###[ TCP ]###\n            sport     = 49667\n            dport     = EtherNet_IP_2\n            seq       = 2390377351\n            ack       = 29171294\n            dataofs   = 5L\n            reserved  = 0L\n            flags     = PA\n            window    = 33436\n            chksum    = 0x2a07\n            urgptr    = 0\n            options   = []\n    ###[ ENIP_TCP ]###\n               command_id= SendUnitData\n               length    = 30\n               session   = 1441794\n               status    = success\n               sender_context= 0\n               options   = 0\n    ###[ ENIP_SendUnitData ]###\n                  interface_handle= 0\n                  timeout   = 0\n                  count     = 2\n                  \\items     \\\n                   |###[ ENIP_SendUnitData_Item ]###\n                   |  type_id   = conn_address\n                   |  length    = 4\n                   |###[ ENIP_ConnectionAddress ]###\n                   |     connection_id= 4290069024\n                   |###[ ENIP_SendUnitData_Item ]###\n                   |  type_id   = conn_packet\n                   |  length    = 10\n                   |###[ ENIP_ConnectionPacket ]###\n                   |     sequence  = 1930\n                   |###[ CIP ]###\n                   |        direction = request\n                   |        service   = Read_Tag_Service\n                   |        \\path      \\\n                   |         |###[ CIP_Path ]###\n                   |         |  wordsize  = 3\n                   |         |  path      = class 0xb2,instance 0x22\n                   |        \\status    \\\n\nMoreover, each component of the packet is accessible in Python.\nFor example, adding ``print(pkt[cip.CIP].path)`` at the end of the script shows the path of the tag being queried in this CIP request::\n\n    [\u003cCIP_Path  wordsize=3 path=class 0xb2,instance 0x22 |\u003e]\n\n\nInterfacing with a PLC\n======================\n\nThe scapy dissectors can be used to craft packet and therefore communicate with a PLC using ENIP and CIP.\nThese communications require several handshakes:\n\n* a TCP handshake to establish a communication channel,\n* an ENIP handshake to register an ENIP session,\n* an optional CIP handshake (with ForwardOpen messages).\n\nThe file ``plc.py`` provides ``PLCClient`` class, which implements an abstraction level of the state of a communication with a PLC.\nHere is for example how to use this class to read tag ``HMI_LIT101`` on the PLC sitting at address ``192.168.1.10``:\n\n.. code-block:: python\n\n    import logging\n    import sys\n\n    from cip import CIP, CIP_Path\n    import plc\n\n    logging.basicConfig(format='[%(levelname)s] %(message)s', level=logging.DEBUG)\n\n    # Connect to PLC\n    client = plc.PLCClient('192.168.1.10')\n    if not client.connected:\n        sys.exit(1)\n    print(\"Established session {}\".format(client.session_id))\n\n    if not client.forward_open():\n        sys.exit(1)\n\n    # Send a CIP ReadTag request\n    cippkt = CIP(service=0x4c, path=CIP_Path.make_str(\"HMI_LIT101\"))\n    client.send_unit_cip(cippkt)\n\n    # Receive the response and show it\n    resppkt = client.recv_enippkt()\n    resppkt[CIP].show()\n\n    # Close the connection\n    client.forward_close()\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscy-phy%2Fscapy-cip-enip","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fscy-phy%2Fscapy-cip-enip","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fscy-phy%2Fscapy-cip-enip/lists"}