@netkitty/codec 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/LICENSE +21 -0
- package/README.md +352 -0
- package/README.zh-CN.md +342 -0
- package/dist/Codec.d.ts +133 -0
- package/dist/Codec.js +632 -0
- package/dist/PacketHeaders.d.ts +189 -0
- package/dist/PacketHeaders.js +384 -0
- package/dist/abstracts/BaseHeader.d.ts +325 -0
- package/dist/abstracts/BaseHeader.js +734 -0
- package/dist/errors/CodecSchemaValidateError.d.ts +4 -0
- package/dist/errors/CodecSchemaValidateError.js +11 -0
- package/dist/headers/ADSAMS.d.ts +33 -0
- package/dist/headers/ADSAMS.js +208 -0
- package/dist/headers/AH.d.ts +28 -0
- package/dist/headers/AH.js +137 -0
- package/dist/headers/AMQP.d.ts +31 -0
- package/dist/headers/AMQP.js +316 -0
- package/dist/headers/ARP.d.ts +26 -0
- package/dist/headers/ARP.js +243 -0
- package/dist/headers/BACnetIP.d.ts +27 -0
- package/dist/headers/BACnetIP.js +97 -0
- package/dist/headers/BFD.d.ts +28 -0
- package/dist/headers/BFD.js +155 -0
- package/dist/headers/BGP.d.ts +27 -0
- package/dist/headers/BGP.js +111 -0
- package/dist/headers/BSAPIP.d.ts +33 -0
- package/dist/headers/BSAPIP.js +78 -0
- package/dist/headers/Babel.d.ts +32 -0
- package/dist/headers/Babel.js +224 -0
- package/dist/headers/BitTorrent.d.ts +28 -0
- package/dist/headers/BitTorrent.js +72 -0
- package/dist/headers/C37118.d.ts +26 -0
- package/dist/headers/C37118.js +147 -0
- package/dist/headers/CAPWAP.d.ts +38 -0
- package/dist/headers/CAPWAP.js +275 -0
- package/dist/headers/CDP.d.ts +25 -0
- package/dist/headers/CDP.js +117 -0
- package/dist/headers/CMS.d.ts +33 -0
- package/dist/headers/CMS.js +238 -0
- package/dist/headers/COTP.d.ts +30 -0
- package/dist/headers/COTP.js +193 -0
- package/dist/headers/CassandraCQL.d.ts +28 -0
- package/dist/headers/CassandraCQL.js +117 -0
- package/dist/headers/CoAP.d.ts +29 -0
- package/dist/headers/CoAP.js +140 -0
- package/dist/headers/Codesys.d.ts +32 -0
- package/dist/headers/Codesys.js +119 -0
- package/dist/headers/Collectd.d.ts +29 -0
- package/dist/headers/Collectd.js +154 -0
- package/dist/headers/DCCP.d.ts +30 -0
- package/dist/headers/DCCP.js +204 -0
- package/dist/headers/DHCP.d.ts +26 -0
- package/dist/headers/DHCP.js +148 -0
- package/dist/headers/DHCPFailover.d.ts +30 -0
- package/dist/headers/DHCPFailover.js +104 -0
- package/dist/headers/DHCPv6.d.ts +25 -0
- package/dist/headers/DHCPv6.js +145 -0
- package/dist/headers/DNP3.d.ts +27 -0
- package/dist/headers/DNP3.js +150 -0
- package/dist/headers/DNS.d.ts +55 -0
- package/dist/headers/DNS.js +309 -0
- package/dist/headers/DTLS.d.ts +33 -0
- package/dist/headers/DTLS.js +142 -0
- package/dist/headers/Diameter.d.ts +34 -0
- package/dist/headers/Diameter.js +229 -0
- package/dist/headers/EAPOL.d.ts +32 -0
- package/dist/headers/EAPOL.js +135 -0
- package/dist/headers/EIGRP.d.ts +28 -0
- package/dist/headers/EIGRP.js +165 -0
- package/dist/headers/ENIP.d.ts +31 -0
- package/dist/headers/ENIP.js +164 -0
- package/dist/headers/ESP.d.ts +27 -0
- package/dist/headers/ESP.js +140 -0
- package/dist/headers/Elasticsearch.d.ts +30 -0
- package/dist/headers/Elasticsearch.js +125 -0
- package/dist/headers/EtherCAT.d.ts +35 -0
- package/dist/headers/EtherCAT.js +150 -0
- package/dist/headers/EthernetII.d.ts +28 -0
- package/dist/headers/EthernetII.js +117 -0
- package/dist/headers/FCoE.d.ts +38 -0
- package/dist/headers/FCoE.js +210 -0
- package/dist/headers/FTP.d.ts +34 -0
- package/dist/headers/FTP.js +158 -0
- package/dist/headers/Finger.d.ts +41 -0
- package/dist/headers/Finger.js +135 -0
- package/dist/headers/FoundationFieldbusHSE.d.ts +43 -0
- package/dist/headers/FoundationFieldbusHSE.js +163 -0
- package/dist/headers/GELF.d.ts +35 -0
- package/dist/headers/GELF.js +261 -0
- package/dist/headers/GENEVE.d.ts +26 -0
- package/dist/headers/GENEVE.js +209 -0
- package/dist/headers/GESRTP.d.ts +32 -0
- package/dist/headers/GESRTP.js +141 -0
- package/dist/headers/GLBP.d.ts +29 -0
- package/dist/headers/GLBP.js +159 -0
- package/dist/headers/GRE.d.ts +27 -0
- package/dist/headers/GRE.js +181 -0
- package/dist/headers/GTPU.d.ts +25 -0
- package/dist/headers/GTPU.js +203 -0
- package/dist/headers/GTPv2C.d.ts +30 -0
- package/dist/headers/GTPv2C.js +281 -0
- package/dist/headers/GitProtocol.d.ts +34 -0
- package/dist/headers/GitProtocol.js +141 -0
- package/dist/headers/Goose.d.ts +115 -0
- package/dist/headers/Goose.js +1067 -0
- package/dist/headers/Gopher.d.ts +43 -0
- package/dist/headers/Gopher.js +182 -0
- package/dist/headers/HARTIP.d.ts +30 -0
- package/dist/headers/HARTIP.js +145 -0
- package/dist/headers/HSR.d.ts +27 -0
- package/dist/headers/HSR.js +105 -0
- package/dist/headers/HSRP.d.ts +26 -0
- package/dist/headers/HSRP.js +173 -0
- package/dist/headers/HTTP.d.ts +32 -0
- package/dist/headers/HTTP.js +153 -0
- package/dist/headers/HTTP2.d.ts +34 -0
- package/dist/headers/HTTP2.js +190 -0
- package/dist/headers/IAX2.d.ts +33 -0
- package/dist/headers/IAX2.js +274 -0
- package/dist/headers/ICMP.d.ts +15 -0
- package/dist/headers/ICMP.js +148 -0
- package/dist/headers/ICMPv6.d.ts +15 -0
- package/dist/headers/ICMPv6.js +129 -0
- package/dist/headers/IEC104_I_Frame.d.ts +23 -0
- package/dist/headers/IEC104_I_Frame.js +6489 -0
- package/dist/headers/IEC104_S_Frame.d.ts +26 -0
- package/dist/headers/IEC104_S_Frame.js +135 -0
- package/dist/headers/IEC104_U_Frame.d.ts +27 -0
- package/dist/headers/IEC104_U_Frame.js +176 -0
- package/dist/headers/IEC61850SampledValues.d.ts +20 -0
- package/dist/headers/IEC61850SampledValues.js +420 -0
- package/dist/headers/IGMP.d.ts +31 -0
- package/dist/headers/IGMP.js +274 -0
- package/dist/headers/IMAP.d.ts +32 -0
- package/dist/headers/IMAP.js +185 -0
- package/dist/headers/IPFIX.d.ts +29 -0
- package/dist/headers/IPFIX.js +156 -0
- package/dist/headers/IPv4.d.ts +20 -0
- package/dist/headers/IPv4.js +370 -0
- package/dist/headers/IPv6.d.ts +29 -0
- package/dist/headers/IPv6.js +209 -0
- package/dist/headers/IPv6HopByHopOptions.d.ts +81 -0
- package/dist/headers/IPv6HopByHopOptions.js +495 -0
- package/dist/headers/IRC.d.ts +34 -0
- package/dist/headers/IRC.js +175 -0
- package/dist/headers/ISAKMP.d.ts +29 -0
- package/dist/headers/ISAKMP.js +197 -0
- package/dist/headers/ISCSI.d.ts +39 -0
- package/dist/headers/ISCSI.js +289 -0
- package/dist/headers/ISIS.d.ts +25 -0
- package/dist/headers/ISIS.js +79 -0
- package/dist/headers/ISOSession.d.ts +27 -0
- package/dist/headers/ISOSession.js +343 -0
- package/dist/headers/Ident.d.ts +42 -0
- package/dist/headers/Ident.js +184 -0
- package/dist/headers/KNXnetIP.d.ts +30 -0
- package/dist/headers/KNXnetIP.js +135 -0
- package/dist/headers/Kafka.d.ts +35 -0
- package/dist/headers/Kafka.js +128 -0
- package/dist/headers/Kerberos.d.ts +30 -0
- package/dist/headers/Kerberos.js +217 -0
- package/dist/headers/L2TP.d.ts +26 -0
- package/dist/headers/L2TP.js +297 -0
- package/dist/headers/LACP.d.ts +31 -0
- package/dist/headers/LACP.js +151 -0
- package/dist/headers/LDAP.d.ts +31 -0
- package/dist/headers/LDAP.js +226 -0
- package/dist/headers/LDP.d.ts +31 -0
- package/dist/headers/LDP.js +138 -0
- package/dist/headers/LISP.d.ts +30 -0
- package/dist/headers/LISP.js +103 -0
- package/dist/headers/LLC.d.ts +27 -0
- package/dist/headers/LLC.js +81 -0
- package/dist/headers/LLDP.d.ts +26 -0
- package/dist/headers/LLDP.js +126 -0
- package/dist/headers/LLMNR.d.ts +23 -0
- package/dist/headers/LLMNR.js +40 -0
- package/dist/headers/LPD.d.ts +31 -0
- package/dist/headers/LPD.js +159 -0
- package/dist/headers/MACsec.d.ts +34 -0
- package/dist/headers/MACsec.js +178 -0
- package/dist/headers/MDNS.d.ts +26 -0
- package/dist/headers/MDNS.js +45 -0
- package/dist/headers/MGCP.d.ts +30 -0
- package/dist/headers/MGCP.js +155 -0
- package/dist/headers/MMS.d.ts +29 -0
- package/dist/headers/MMS.js +243 -0
- package/dist/headers/MPLS.d.ts +31 -0
- package/dist/headers/MPLS.js +145 -0
- package/dist/headers/MQTT.d.ts +30 -0
- package/dist/headers/MQTT.js +173 -0
- package/dist/headers/MQTTSN.d.ts +34 -0
- package/dist/headers/MQTTSN.js +177 -0
- package/dist/headers/MarkerProtocol.d.ts +32 -0
- package/dist/headers/MarkerProtocol.js +153 -0
- package/dist/headers/Megaco.d.ts +32 -0
- package/dist/headers/Megaco.js +144 -0
- package/dist/headers/Memcached.d.ts +44 -0
- package/dist/headers/Memcached.js +285 -0
- package/dist/headers/ModbusTCP.d.ts +25 -0
- package/dist/headers/ModbusTCP.js +99 -0
- package/dist/headers/ModbusUDP.d.ts +26 -0
- package/dist/headers/ModbusUDP.js +100 -0
- package/dist/headers/MongoDB.d.ts +33 -0
- package/dist/headers/MongoDB.js +143 -0
- package/dist/headers/MySQL.d.ts +30 -0
- package/dist/headers/MySQL.js +114 -0
- package/dist/headers/NATS.d.ts +29 -0
- package/dist/headers/NATS.js +135 -0
- package/dist/headers/NBDS.d.ts +34 -0
- package/dist/headers/NBDS.js +176 -0
- package/dist/headers/NBNS.d.ts +34 -0
- package/dist/headers/NBNS.js +78 -0
- package/dist/headers/NBSS.d.ts +36 -0
- package/dist/headers/NBSS.js +137 -0
- package/dist/headers/NFS.d.ts +36 -0
- package/dist/headers/NFS.js +273 -0
- package/dist/headers/NHRP.d.ts +32 -0
- package/dist/headers/NHRP.js +154 -0
- package/dist/headers/NNTP.d.ts +35 -0
- package/dist/headers/NNTP.js +162 -0
- package/dist/headers/NTP.d.ts +18 -0
- package/dist/headers/NTP.js +73 -0
- package/dist/headers/NetFlowV5.d.ts +28 -0
- package/dist/headers/NetFlowV5.js +205 -0
- package/dist/headers/OLSR.d.ts +31 -0
- package/dist/headers/OLSR.js +213 -0
- package/dist/headers/OPCUA.d.ts +33 -0
- package/dist/headers/OPCUA.js +165 -0
- package/dist/headers/OPCUAPubSub.d.ts +33 -0
- package/dist/headers/OPCUAPubSub.js +144 -0
- package/dist/headers/OSPF.d.ts +31 -0
- package/dist/headers/OSPF.js +365 -0
- package/dist/headers/OmronFINS.d.ts +31 -0
- package/dist/headers/OmronFINS.js +90 -0
- package/dist/headers/OpenFlow.d.ts +30 -0
- package/dist/headers/OpenFlow.js +113 -0
- package/dist/headers/OpenVPN.d.ts +35 -0
- package/dist/headers/OpenVPN.js +214 -0
- package/dist/headers/PCWorx.d.ts +35 -0
- package/dist/headers/PCWorx.js +115 -0
- package/dist/headers/PIM.d.ts +27 -0
- package/dist/headers/PIM.js +129 -0
- package/dist/headers/POP3.d.ts +31 -0
- package/dist/headers/POP3.js +152 -0
- package/dist/headers/POWERLINK.d.ts +28 -0
- package/dist/headers/POWERLINK.js +116 -0
- package/dist/headers/PPPoEDiscovery.d.ts +29 -0
- package/dist/headers/PPPoEDiscovery.js +198 -0
- package/dist/headers/PPPoESession.d.ts +28 -0
- package/dist/headers/PPPoESession.js +125 -0
- package/dist/headers/PPTP.d.ts +30 -0
- package/dist/headers/PPTP.js +122 -0
- package/dist/headers/PROFINETRT.d.ts +28 -0
- package/dist/headers/PROFINETRT.js +74 -0
- package/dist/headers/PTP.d.ts +34 -0
- package/dist/headers/PTP.js +213 -0
- package/dist/headers/PostgreSQL.d.ts +40 -0
- package/dist/headers/PostgreSQL.js +236 -0
- package/dist/headers/QUIC.d.ts +34 -0
- package/dist/headers/QUIC.js +308 -0
- package/dist/headers/RADIUS.d.ts +24 -0
- package/dist/headers/RADIUS.js +138 -0
- package/dist/headers/RDP.d.ts +27 -0
- package/dist/headers/RDP.js +93 -0
- package/dist/headers/RFB.d.ts +39 -0
- package/dist/headers/RFB.js +151 -0
- package/dist/headers/RGoose.d.ts +72 -0
- package/dist/headers/RGoose.js +340 -0
- package/dist/headers/RIP.d.ts +29 -0
- package/dist/headers/RIP.js +133 -0
- package/dist/headers/RIPng.d.ts +26 -0
- package/dist/headers/RIPng.js +140 -0
- package/dist/headers/RMCP.d.ts +26 -0
- package/dist/headers/RMCP.js +155 -0
- package/dist/headers/RSVP.d.ts +31 -0
- package/dist/headers/RSVP.js +263 -0
- package/dist/headers/RTCP.d.ts +34 -0
- package/dist/headers/RTCP.js +217 -0
- package/dist/headers/RTP.d.ts +33 -0
- package/dist/headers/RTP.js +291 -0
- package/dist/headers/RTPS.d.ts +33 -0
- package/dist/headers/RTPS.js +182 -0
- package/dist/headers/RTSP.d.ts +36 -0
- package/dist/headers/RTSP.js +184 -0
- package/dist/headers/RawData.d.ts +17 -0
- package/dist/headers/RawData.js +43 -0
- package/dist/headers/Redis.d.ts +32 -0
- package/dist/headers/Redis.js +202 -0
- package/dist/headers/Rlogin.d.ts +42 -0
- package/dist/headers/Rlogin.js +139 -0
- package/dist/headers/Rsync.d.ts +28 -0
- package/dist/headers/Rsync.js +117 -0
- package/dist/headers/S7comm.d.ts +36 -0
- package/dist/headers/S7comm.js +244 -0
- package/dist/headers/SCTP.d.ts +35 -0
- package/dist/headers/SCTP.js +174 -0
- package/dist/headers/SFlow.d.ts +29 -0
- package/dist/headers/SFlow.js +242 -0
- package/dist/headers/SIP.d.ts +27 -0
- package/dist/headers/SIP.js +146 -0
- package/dist/headers/SLMP.d.ts +36 -0
- package/dist/headers/SLMP.js +154 -0
- package/dist/headers/SLP.d.ts +30 -0
- package/dist/headers/SLP.js +207 -0
- package/dist/headers/SLPv1.d.ts +32 -0
- package/dist/headers/SLPv1.js +138 -0
- package/dist/headers/SMB1.d.ts +37 -0
- package/dist/headers/SMB1.js +200 -0
- package/dist/headers/SMB2.d.ts +36 -0
- package/dist/headers/SMB2.js +203 -0
- package/dist/headers/SMPP.d.ts +33 -0
- package/dist/headers/SMPP.js +119 -0
- package/dist/headers/SMTP.d.ts +33 -0
- package/dist/headers/SMTP.js +157 -0
- package/dist/headers/SNAP.d.ts +22 -0
- package/dist/headers/SNAP.js +68 -0
- package/dist/headers/SNMP.d.ts +28 -0
- package/dist/headers/SNMP.js +302 -0
- package/dist/headers/SOCKS4.d.ts +42 -0
- package/dist/headers/SOCKS4.js +302 -0
- package/dist/headers/SOCKS5.d.ts +45 -0
- package/dist/headers/SOCKS5.js +223 -0
- package/dist/headers/SSDP.d.ts +27 -0
- package/dist/headers/SSDP.js +161 -0
- package/dist/headers/SSH.d.ts +44 -0
- package/dist/headers/SSH.js +274 -0
- package/dist/headers/STOMP.d.ts +48 -0
- package/dist/headers/STOMP.js +177 -0
- package/dist/headers/STP.d.ts +26 -0
- package/dist/headers/STP.js +150 -0
- package/dist/headers/STUN.d.ts +25 -0
- package/dist/headers/STUN.js +183 -0
- package/dist/headers/SercosIII.d.ts +43 -0
- package/dist/headers/SercosIII.js +199 -0
- package/dist/headers/Skinny.d.ts +32 -0
- package/dist/headers/Skinny.js +139 -0
- package/dist/headers/StatsD.d.ts +27 -0
- package/dist/headers/StatsD.js +134 -0
- package/dist/headers/SunRPC.d.ts +34 -0
- package/dist/headers/SunRPC.js +268 -0
- package/dist/headers/Syslog.d.ts +21 -0
- package/dist/headers/Syslog.js +91 -0
- package/dist/headers/TCP.d.ts +19 -0
- package/dist/headers/TCP.js +905 -0
- package/dist/headers/TFTP.d.ts +28 -0
- package/dist/headers/TFTP.js +224 -0
- package/dist/headers/TLS_Alert.d.ts +24 -0
- package/dist/headers/TLS_Alert.js +639 -0
- package/dist/headers/TLS_ApplicationData.d.ts +24 -0
- package/dist/headers/TLS_ApplicationData.js +170 -0
- package/dist/headers/TLS_ChangeCipherSpec.d.ts +23 -0
- package/dist/headers/TLS_ChangeCipherSpec.js +168 -0
- package/dist/headers/TLS_Handshake.d.ts +65 -0
- package/dist/headers/TLS_Handshake.js +860 -0
- package/dist/headers/TLS_Heartbeat.d.ts +27 -0
- package/dist/headers/TLS_Heartbeat.js +247 -0
- package/dist/headers/TPKT.d.ts +26 -0
- package/dist/headers/TPKT.js +99 -0
- package/dist/headers/TacacsPlus.d.ts +27 -0
- package/dist/headers/TacacsPlus.js +133 -0
- package/dist/headers/Telnet.d.ts +40 -0
- package/dist/headers/Telnet.js +193 -0
- package/dist/headers/Teredo.d.ts +40 -0
- package/dist/headers/Teredo.js +251 -0
- package/dist/headers/TimeProtocol.d.ts +25 -0
- package/dist/headers/TimeProtocol.js +53 -0
- package/dist/headers/UDP.d.ts +19 -0
- package/dist/headers/UDP.js +171 -0
- package/dist/headers/VLAN_802dot1Q.d.ts +24 -0
- package/dist/headers/VLAN_802dot1Q.js +96 -0
- package/dist/headers/VRRP.d.ts +26 -0
- package/dist/headers/VRRP.js +309 -0
- package/dist/headers/VXLAN.d.ts +24 -0
- package/dist/headers/VXLAN.js +75 -0
- package/dist/headers/WCCP.d.ts +29 -0
- package/dist/headers/WCCP.js +117 -0
- package/dist/headers/WHOIS.d.ts +37 -0
- package/dist/headers/WHOIS.js +126 -0
- package/dist/headers/WSDiscovery.d.ts +29 -0
- package/dist/headers/WSDiscovery.js +118 -0
- package/dist/headers/WakeOnLAN.d.ts +30 -0
- package/dist/headers/WakeOnLAN.js +126 -0
- package/dist/headers/WebSocket.d.ts +26 -0
- package/dist/headers/WebSocket.js +173 -0
- package/dist/headers/WireGuard.d.ts +38 -0
- package/dist/headers/WireGuard.js +216 -0
- package/dist/headers/XMPP.d.ts +37 -0
- package/dist/headers/XMPP.js +149 -0
- package/dist/headers/Zabbix.d.ts +35 -0
- package/dist/headers/Zabbix.js +153 -0
- package/dist/headers/cms/AcsiPdu.d.ts +45 -0
- package/dist/headers/cms/AcsiPdu.js +112 -0
- package/dist/headers/cms/PerDecoder.d.ts +68 -0
- package/dist/headers/cms/PerDecoder.js +211 -0
- package/dist/headers/cms/PerReader.d.ts +64 -0
- package/dist/headers/cms/PerReader.js +155 -0
- package/dist/helper/BufferToHex.d.ts +5 -0
- package/dist/helper/BufferToHex.js +10 -0
- package/dist/helper/BufferToIP.d.ts +12 -0
- package/dist/helper/BufferToIP.js +23 -0
- package/dist/helper/BufferToNumber.d.ts +18 -0
- package/dist/helper/BufferToNumber.js +47 -0
- package/dist/helper/HexToBuffer.d.ts +7 -0
- package/dist/helper/HexToBuffer.js +27 -0
- package/dist/helper/HexToNumber.d.ts +18 -0
- package/dist/helper/HexToNumber.js +48 -0
- package/dist/helper/IPToBuffer.d.ts +12 -0
- package/dist/helper/IPToBuffer.js +34 -0
- package/dist/helper/NumberToBERBuffer.d.ts +18 -0
- package/dist/helper/NumberToBERBuffer.js +31 -0
- package/dist/helper/NumberToBERHex.d.ts +18 -0
- package/dist/helper/NumberToBERHex.js +52 -0
- package/dist/helper/NumberToBuffer.d.ts +18 -0
- package/dist/helper/NumberToBuffer.js +38 -0
- package/dist/helper/NumberToHex.d.ts +18 -0
- package/dist/helper/NumberToHex.js +35 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.js +113 -0
- package/dist/lib/FlexibleObject.d.ts +27 -0
- package/dist/lib/FlexibleObject.js +113 -0
- package/dist/lib/GetBERIntegerLengthFromBuffer.d.ts +6 -0
- package/dist/lib/GetBERIntegerLengthFromBuffer.js +16 -0
- package/dist/lib/ProcessPacketPostHandlers.d.ts +13 -0
- package/dist/lib/ProcessPacketPostHandlers.js +53 -0
- package/dist/lib/SortPostHandlers.d.ts +7 -0
- package/dist/lib/SortPostHandlers.js +11 -0
- package/dist/lib/StringContentEncodingEnum.d.ts +10 -0
- package/dist/lib/StringContentEncodingEnum.js +14 -0
- package/dist/schema/ProtocolFieldJSONSchema.d.ts +35 -0
- package/dist/schema/ProtocolFieldJSONSchema.js +2 -0
- package/dist/schema/ProtocolFieldJSONSchemaDefinition.d.ts +2 -0
- package/dist/schema/ProtocolFieldJSONSchemaDefinition.js +2 -0
- package/dist/schema/ProtocolJSONSchema.d.ts +32 -0
- package/dist/schema/ProtocolJSONSchema.js +2 -0
- package/dist/types/CodecData.d.ts +7 -0
- package/dist/types/CodecData.js +2 -0
- package/dist/types/CodecDecodeResult.d.ts +10 -0
- package/dist/types/CodecDecodeResult.js +2 -0
- package/dist/types/CodecEncodeInput.d.ts +2 -0
- package/dist/types/CodecEncodeInput.js +2 -0
- package/dist/types/CodecEncodeResult.d.ts +5 -0
- package/dist/types/CodecEncodeResult.js +2 -0
- package/dist/types/CodecErrorInfo.d.ts +5 -0
- package/dist/types/CodecErrorInfo.js +2 -0
- package/dist/types/CodecModule.d.ts +2 -0
- package/dist/types/CodecModule.js +2 -0
- package/dist/types/CodecModuleConstructor.d.ts +2 -0
- package/dist/types/CodecModuleConstructor.js +2 -0
- package/dist/types/CodecSchema.d.ts +6 -0
- package/dist/types/CodecSchema.js +2 -0
- package/dist/types/DemuxProducer.d.ts +23 -0
- package/dist/types/DemuxProducer.js +2 -0
- package/dist/types/Dissection.d.ts +23 -0
- package/dist/types/Dissection.js +2 -0
- package/dist/types/HeaderTreeNode.d.ts +4 -0
- package/dist/types/HeaderTreeNode.js +2 -0
- package/dist/types/LayerGraph.d.ts +32 -0
- package/dist/types/LayerGraph.js +2 -0
- package/dist/types/PostHandlerItem.d.ts +4 -0
- package/dist/types/PostHandlerItem.js +2 -0
- package/package.json +141 -0
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CMS = void 0;
|
|
4
|
+
const BaseHeader_1 = require("../abstracts/BaseHeader");
|
|
5
|
+
const BufferToHex_1 = require("../helper/BufferToHex");
|
|
6
|
+
const HexToBuffer_1 = require("../helper/HexToBuffer");
|
|
7
|
+
const PerDecoder_1 = require("./cms/PerDecoder");
|
|
8
|
+
const AcsiPdu_1 = require("./cms/AcsiPdu");
|
|
9
|
+
/**
|
|
10
|
+
* CMS — China smart-substation communication (DL/T 2811-2024, "变电站二次系统通信报文规范"), the
|
|
11
|
+
* State-Grid replacement for IEC 61850 MMS that maps ACSI directly onto TCP (port 8102), dropping the
|
|
12
|
+
* OSI upper layers. Per DL/T 2811 §6.1, an Application Protocol Data Unit (APDU) is an Application
|
|
13
|
+
* Protocol Control Header (APCH) followed by an Application Service Data Unit (ASDU):
|
|
14
|
+
*
|
|
15
|
+
* APCH (4 bytes): Control Code CC — Next(bit8) + Resp(bit7) + Err(bit6) + bak(bit5) + a 4-bit Protocol
|
|
16
|
+
* type PI (low nibble, = 0x01); Service Code SC (1 byte, §6.1.2 Table 1: 1 Associate,
|
|
17
|
+
* 2 Abort, 3 Release, 48 GetDataValues, 83 GetAllDataValues, 154 AssociateNegotiate,
|
|
18
|
+
* 155 GetAllDataDefinition, …); Frame Length FL (2 bytes, little-endian, the APDU
|
|
19
|
+
* length excluding the APCH).
|
|
20
|
+
* ASDU (FL bytes): Service Request Id ReqID (2 bytes, little-endian, §6.2 — 1..65535, 0 for Report)
|
|
21
|
+
* + the service data area (encoded per the SC, kept verbatim here).
|
|
22
|
+
*
|
|
23
|
+
* An empty frame (§6.3) has FL=0 (APCH only) or FL=2 (APCH+ReqID). A large ASDU is framed (§6.5) with
|
|
24
|
+
* the Next bit set. A CMS PDU can also exceed one TCP segment; this single-packet stateless codec
|
|
25
|
+
* structures the APCH + the ASDU bytes present in the packet, leaving TCP-stream reassembly to a higher
|
|
26
|
+
* layer (mid-PDU continuation segments carry no APCH — their first byte's low nibble is not the PI 0x01
|
|
27
|
+
* — so they fall to raw). A single frame round-trips byte-for-byte.
|
|
28
|
+
*/
|
|
29
|
+
class CMS extends BaseHeader_1.BaseHeader {
|
|
30
|
+
constructor() {
|
|
31
|
+
super(...arguments);
|
|
32
|
+
this.id = 'cms';
|
|
33
|
+
this.name = 'CMS (China Substation Communication, DL/T 2811)';
|
|
34
|
+
this.nickname = 'CMS';
|
|
35
|
+
this.matchKeys = ['tcpport:8102', 'tcpport:9102'];
|
|
36
|
+
//A leaf for this slice — the service data area is kept verbatim (its per-service ACSI encoding, DL/T
|
|
37
|
+
//2811 §6.10 / §7, is a later slice).
|
|
38
|
+
this.demuxProducers = [];
|
|
39
|
+
}
|
|
40
|
+
static #schemaCache;
|
|
41
|
+
get SCHEMA() {
|
|
42
|
+
return (CMS.#schemaCache ??= CMS.#buildSchema());
|
|
43
|
+
}
|
|
44
|
+
static #bit(name, bitOffset, label) {
|
|
45
|
+
return {
|
|
46
|
+
type: 'boolean', label: label,
|
|
47
|
+
decode: function () {
|
|
48
|
+
this.instance[name].setValue(!!this.readBits(0, 1, bitOffset, 1));
|
|
49
|
+
},
|
|
50
|
+
encode: function () {
|
|
51
|
+
this.writeBits(0, 1, bitOffset, 1, this.instance[name].getValue(false) ? 1 : 0);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
static #buildSchema() {
|
|
56
|
+
return {
|
|
57
|
+
type: 'object',
|
|
58
|
+
summary: 'CMS SC=${serviceCode} ReqID=${reqId}',
|
|
59
|
+
properties: {
|
|
60
|
+
//==== APCH — Control Code CC (byte 1) ====
|
|
61
|
+
//Next: more frames follow (application-level framing of a large ASDU, §6.5).
|
|
62
|
+
next: this.#bit('next', 0, 'Next'),
|
|
63
|
+
//Resp: this APDU is a response (vs a request).
|
|
64
|
+
resp: this.#bit('resp', 1, 'Resp'),
|
|
65
|
+
//Err: an error response.
|
|
66
|
+
err: this.#bit('err', 2, 'Err'),
|
|
67
|
+
//bak: reserved.
|
|
68
|
+
bak: this.#bit('bak', 3, 'bak'),
|
|
69
|
+
//Protocol type PI — the low nibble, 0x01 for DL/T 2811.
|
|
70
|
+
protocolType: {
|
|
71
|
+
type: 'integer', label: 'Protocol Type', minimum: 0, maximum: 15,
|
|
72
|
+
decode: function () {
|
|
73
|
+
this.instance.protocolType.setValue(this.readBits(0, 1, 4, 4));
|
|
74
|
+
},
|
|
75
|
+
encode: function () {
|
|
76
|
+
this.writeBits(0, 1, 4, 4, this.instance.protocolType.getValue(1) & 0x0f);
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
//Service Code SC (byte 2) — the service in the data area (Table 1).
|
|
80
|
+
serviceCode: this.fieldUInt('serviceCode', 1, 1, 'Service Code'),
|
|
81
|
+
//Frame Length FL (bytes 3-4, LITTLE-ENDIAN) — the APDU length excluding the 4-byte APCH,
|
|
82
|
+
//i.e. the ASDU length. Honored verbatim.
|
|
83
|
+
frameLength: {
|
|
84
|
+
type: 'integer', label: 'Frame Length', minimum: 0, maximum: 65535,
|
|
85
|
+
decode: function () {
|
|
86
|
+
const b = this.readBytes(2, 2);
|
|
87
|
+
this.instance.frameLength.setValue((b[0] | (b[1] << 8)) & 0xffff);
|
|
88
|
+
},
|
|
89
|
+
encode: function () {
|
|
90
|
+
let value = this.instance.frameLength.getValue(0);
|
|
91
|
+
if (value > 65535)
|
|
92
|
+
value = 65535;
|
|
93
|
+
if (value < 0)
|
|
94
|
+
value = 0;
|
|
95
|
+
this.writeBytes(2, Buffer.from([value & 0xff, (value >> 8) & 0xff]));
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
//==== ASDU ====
|
|
99
|
+
//Service Request Id ReqID (bytes 5-6, LITTLE-ENDIAN). Present only when the ASDU carries it
|
|
100
|
+
//(FL >= 2); an FL=0 empty frame (§6.3) has no ASDU at all.
|
|
101
|
+
reqId: {
|
|
102
|
+
type: 'integer', label: 'Request Id', minimum: 0, maximum: 65535,
|
|
103
|
+
decode: function () {
|
|
104
|
+
const available = this.packet.length - this.startPos;
|
|
105
|
+
if (this.instance.frameLength.getValue(0) < 2 || available < 6)
|
|
106
|
+
return;
|
|
107
|
+
const b = this.readBytes(4, 2);
|
|
108
|
+
this.instance.reqId.setValue((b[0] | (b[1] << 8)) & 0xffff);
|
|
109
|
+
},
|
|
110
|
+
encode: function () {
|
|
111
|
+
const reqId = this.instance.reqId.getValue();
|
|
112
|
+
if (reqId === undefined || reqId === null)
|
|
113
|
+
return;
|
|
114
|
+
this.writeBytes(4, Buffer.from([reqId & 0xff, (reqId >> 8) & 0xff]));
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
//The service data area (encoded per the Service Code), kept verbatim. Bounded by FL (minus
|
|
118
|
+
//the 2-byte ReqID) and the captured bytes — for a PDU split across TCP segments only the
|
|
119
|
+
//bytes present in this packet are captured; the rest is left to a higher reassembly layer.
|
|
120
|
+
serviceData: {
|
|
121
|
+
type: 'string', label: 'Service Data', contentEncoding: 'hex',
|
|
122
|
+
decode: function () {
|
|
123
|
+
const available = this.packet.length - this.startPos;
|
|
124
|
+
const fl = this.instance.frameLength.getValue(0);
|
|
125
|
+
if (fl < 2)
|
|
126
|
+
return;
|
|
127
|
+
let end = 4 + fl;
|
|
128
|
+
if (end > available)
|
|
129
|
+
end = available;
|
|
130
|
+
//Service data begins after the 2-byte ReqID (offset 6).
|
|
131
|
+
if (end <= 6)
|
|
132
|
+
return;
|
|
133
|
+
const buf = this.readBytes(6, end - 6);
|
|
134
|
+
this.instance.serviceData.setValue((0, BufferToHex_1.BufferToHex)(buf));
|
|
135
|
+
//Display-only: structure the service data area per the Service Code (§6.10, PER).
|
|
136
|
+
const decoded = CMS.#decodeServiceData(this.instance.serviceCode.getValue(0), !!this.instance.resp.getValue(false), !!this.instance.err.getValue(false), buf);
|
|
137
|
+
if (decoded !== undefined) {
|
|
138
|
+
this.instance.serviceDataDecoded.setValue(decoded);
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
//No transcribed structure (e.g. a data/definition response, whose GB/T 33603
|
|
142
|
+
//"M-coding" body framing is not fully specified in the available standards).
|
|
143
|
+
//Best-effort: surface the readable IEC 61850 identifiers (object/attribute names,
|
|
144
|
+
//CDC types, string values) as display metadata — not a structural decode.
|
|
145
|
+
const strings = CMS.#extractStrings(buf);
|
|
146
|
+
if (strings.length)
|
|
147
|
+
this.instance.serviceDataStrings.setValue(strings);
|
|
148
|
+
}
|
|
149
|
+
},
|
|
150
|
+
encode: function () {
|
|
151
|
+
const data = this.instance.serviceData.getValue('');
|
|
152
|
+
if (data)
|
|
153
|
+
this.writeBytes(6, (0, HexToBuffer_1.HexToBuffer)(data));
|
|
154
|
+
}
|
|
155
|
+
},
|
|
156
|
+
//Display-only structured view of the service data area, decoded with ALIGNED BASIC-PER
|
|
157
|
+
//(DL/T 2811 §6.10) per the Service Code. Populated on decode by the serviceData closure
|
|
158
|
+
//above; it has no encode closure, so `serviceData` (hex) stays the authoritative encode
|
|
159
|
+
//form and the structured view can never perturb the re-emitted bytes.
|
|
160
|
+
serviceDataDecoded: { type: 'object', label: 'Service Data (decoded)' },
|
|
161
|
+
//Display-only best-effort readable identifiers extracted from a service data area that has
|
|
162
|
+
//no transcribed structure (the GB/T 33603 M-coded responses). No encode closure.
|
|
163
|
+
serviceDataStrings: { type: 'array', label: 'Readable Identifiers', items: { type: 'string' } }
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Best-effort ALIGNED BASIC-PER decode of the service data area for display. Returns a plain tree
|
|
169
|
+
* {service, direction, …fields} when the Service Code + direction has a transcribed ASN.1 descriptor,
|
|
170
|
+
* `incomplete: true` if the decoder bailed partway, or undefined when nothing is structured (leaving
|
|
171
|
+
* the verbatim hex as the only view). Never throws.
|
|
172
|
+
*/
|
|
173
|
+
/**
|
|
174
|
+
* Best-effort readable-identifier extraction from an M-coded (GB/T 33603) service data area whose exact
|
|
175
|
+
* framing is not fully specified in the available standards. IEC 61850 names/values are length-prefixed
|
|
176
|
+
* in the low 7 bits of a leading octet; this collects each run of `len` identifier characters
|
|
177
|
+
* ([A-Za-z0-9_/]) that starts with a letter — the object/attribute names, CDC types and string values
|
|
178
|
+
* (Mod, stVal, INC, vendor, …). Bounded and never-throwing. This is display metadata, not a structural
|
|
179
|
+
* decode: it makes no claim about the record structure and never affects the re-emitted bytes.
|
|
180
|
+
*/
|
|
181
|
+
static #extractStrings(buf) {
|
|
182
|
+
const isId = (b) => (b >= 0x30 && b <= 0x39) || (b >= 0x41 && b <= 0x5a) || (b >= 0x61 && b <= 0x7a) || b === 0x5f || b === 0x2f;
|
|
183
|
+
const isAlpha = (b) => (b >= 0x41 && b <= 0x5a) || (b >= 0x61 && b <= 0x7a);
|
|
184
|
+
const out = [];
|
|
185
|
+
for (let i = 0; i + 1 < buf.length && out.length < 256; i++) {
|
|
186
|
+
const len = buf[i] & 0x7f;
|
|
187
|
+
if (len < 2 || i + 1 + len > buf.length)
|
|
188
|
+
continue;
|
|
189
|
+
if (!isAlpha(buf[i + 1]))
|
|
190
|
+
continue;
|
|
191
|
+
let ok = true;
|
|
192
|
+
for (let j = 1; j < len; j++)
|
|
193
|
+
if (!isId(buf[i + 1 + j])) {
|
|
194
|
+
ok = false;
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
197
|
+
if (ok) {
|
|
198
|
+
out.push(buf.subarray(i + 1, i + 1 + len).toString('latin1'));
|
|
199
|
+
i += len;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return out;
|
|
203
|
+
}
|
|
204
|
+
static #decodeServiceData(serviceCode, isResponse, isError, buf) {
|
|
205
|
+
const entry = AcsiPdu_1.SERVICE_PDU[serviceCode];
|
|
206
|
+
if (!entry)
|
|
207
|
+
return undefined;
|
|
208
|
+
//Error responses carry a ServiceError, not the normal response PDU — not structured in this slice.
|
|
209
|
+
const type = isError ? undefined : (isResponse ? entry.response : entry.request);
|
|
210
|
+
if (!type)
|
|
211
|
+
return undefined;
|
|
212
|
+
try {
|
|
213
|
+
const decoder = new PerDecoder_1.PerDecoder(buf);
|
|
214
|
+
const tree = decoder.decode(type);
|
|
215
|
+
const head = {
|
|
216
|
+
service: AcsiPdu_1.SERVICE_NAMES[serviceCode] ?? String(serviceCode),
|
|
217
|
+
direction: isResponse ? 'response' : 'request'
|
|
218
|
+
};
|
|
219
|
+
const body = (tree !== null && typeof tree === 'object') ? tree : {};
|
|
220
|
+
return decoder.bailed ? { ...head, ...body, incomplete: true } : { ...head, ...body };
|
|
221
|
+
}
|
|
222
|
+
catch {
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
match() {
|
|
227
|
+
//CMS rides on TCP port 8102 (DL/T 2811 §6.6); some deployments also expose it on 9102 (the 国密
|
|
228
|
+
//TLCP port), where it can appear in the clear. Require the 4-byte APCH and the Protocol type
|
|
229
|
+
//PI = 0x01 in the low nibble of the Control Code, so non-CMS traffic and mid-PDU TCP-continuation
|
|
230
|
+
//segments (which begin with ASDU data bytes, not an APCH) fall through to raw.
|
|
231
|
+
if (!this.prevCodecModule || this.prevCodecModule.id !== 'tcp')
|
|
232
|
+
return false;
|
|
233
|
+
if (this.packet.length - this.startPos < 4)
|
|
234
|
+
return false;
|
|
235
|
+
return (this.readBytes(0, 1, true)[0] & 0x0f) === 0x01;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
exports.CMS = CMS;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* COTP — the ISO 8073 / ITU-T X.224 Connection-Oriented Transport Protocol TPDU, carried inside a TPKT
|
|
6
|
+
* PDU (RFC 1006) and the transport layer of the IEC 61850 MMS / substation ISO stack. Each TPDU begins
|
|
7
|
+
* with a Length Indicator (LI) — the number of header octets that FOLLOW the LI byte (it counts neither
|
|
8
|
+
* the LI itself nor the user data) — then the PDU Type octet (its high nibble is the type code: 0xF0 = DT
|
|
9
|
+
* Data, 0xE0 = CR Connect Request, 0xD0 = CC Connect Confirm, 0x80 = DR Disconnect Request, 0x50 = ER
|
|
10
|
+
* Error, …), then type-specific header fields, then the user data (the ISO Session / Presentation / ACSE /
|
|
11
|
+
* MMS bytes above).
|
|
12
|
+
*
|
|
13
|
+
* The single most common TPDU — DT (Data, 0xF0) — is structured: the octet after the PDU Type carries EOT
|
|
14
|
+
* (bit 7, "end of TSDU") and the 7-bit TPDU-NR. Every OTHER TPDU type keeps its type-specific header
|
|
15
|
+
* verbatim as `headerRest` hex (bounded by LI), so any TPDU round-trips byte-for-byte without fully
|
|
16
|
+
* modelling each variant. `pduType` is stored as the FULL octet (e.g. DT = 0xF0 = 240), preserving the low
|
|
17
|
+
* nibble (CDT credit on CR/CC, etc.) so nothing is lost. The user data is kept verbatim as `data` hex,
|
|
18
|
+
* bounded by the parent TPKT's Length when present; sub-decoding the session/MMS layers above is deferred.
|
|
19
|
+
* COTP is therefore effectively a leaf for now.
|
|
20
|
+
*/
|
|
21
|
+
export declare class COTP extends BaseHeader {
|
|
22
|
+
#private;
|
|
23
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly nickname: string;
|
|
27
|
+
readonly matchKeys: string[];
|
|
28
|
+
match(): boolean;
|
|
29
|
+
readonly demuxProducers: DemuxProducer[];
|
|
30
|
+
}
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.COTP = void 0;
|
|
4
|
+
const BaseHeader_1 = require("../abstracts/BaseHeader");
|
|
5
|
+
const BufferToHex_1 = require("../helper/BufferToHex");
|
|
6
|
+
const HexToBuffer_1 = require("../helper/HexToBuffer");
|
|
7
|
+
const BufferToNumber_1 = require("../helper/BufferToNumber");
|
|
8
|
+
const NumberToBuffer_1 = require("../helper/NumberToBuffer");
|
|
9
|
+
const StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
|
|
10
|
+
/**
|
|
11
|
+
* COTP — the ISO 8073 / ITU-T X.224 Connection-Oriented Transport Protocol TPDU, carried inside a TPKT
|
|
12
|
+
* PDU (RFC 1006) and the transport layer of the IEC 61850 MMS / substation ISO stack. Each TPDU begins
|
|
13
|
+
* with a Length Indicator (LI) — the number of header octets that FOLLOW the LI byte (it counts neither
|
|
14
|
+
* the LI itself nor the user data) — then the PDU Type octet (its high nibble is the type code: 0xF0 = DT
|
|
15
|
+
* Data, 0xE0 = CR Connect Request, 0xD0 = CC Connect Confirm, 0x80 = DR Disconnect Request, 0x50 = ER
|
|
16
|
+
* Error, …), then type-specific header fields, then the user data (the ISO Session / Presentation / ACSE /
|
|
17
|
+
* MMS bytes above).
|
|
18
|
+
*
|
|
19
|
+
* The single most common TPDU — DT (Data, 0xF0) — is structured: the octet after the PDU Type carries EOT
|
|
20
|
+
* (bit 7, "end of TSDU") and the 7-bit TPDU-NR. Every OTHER TPDU type keeps its type-specific header
|
|
21
|
+
* verbatim as `headerRest` hex (bounded by LI), so any TPDU round-trips byte-for-byte without fully
|
|
22
|
+
* modelling each variant. `pduType` is stored as the FULL octet (e.g. DT = 0xF0 = 240), preserving the low
|
|
23
|
+
* nibble (CDT credit on CR/CC, etc.) so nothing is lost. The user data is kept verbatim as `data` hex,
|
|
24
|
+
* bounded by the parent TPKT's Length when present; sub-decoding the session/MMS layers above is deferred.
|
|
25
|
+
* COTP is therefore effectively a leaf for now.
|
|
26
|
+
*/
|
|
27
|
+
class COTP extends BaseHeader_1.BaseHeader {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
this.id = 'cotp';
|
|
31
|
+
this.name = 'COTP';
|
|
32
|
+
this.nickname = 'COTP';
|
|
33
|
+
//No demux keys: COTP is an unkeyed content-heuristic child that only rides on top of TPKT.
|
|
34
|
+
this.matchKeys = [];
|
|
35
|
+
//Effectively a leaf for now — the session/MMS layers above are kept verbatim and decoded later.
|
|
36
|
+
this.demuxProducers = [];
|
|
37
|
+
}
|
|
38
|
+
static #schemaCache;
|
|
39
|
+
get SCHEMA() {
|
|
40
|
+
return (COTP.#schemaCache ??= COTP.#buildSchema());
|
|
41
|
+
}
|
|
42
|
+
/** DT (Data) is identified by the high nibble of the PDU Type octet being 0xF. */
|
|
43
|
+
static #isDT(pduType) {
|
|
44
|
+
return (pduType & 0xf0) === 0xf0;
|
|
45
|
+
}
|
|
46
|
+
static #buildSchema() {
|
|
47
|
+
return {
|
|
48
|
+
type: 'object',
|
|
49
|
+
summary: 'COTP type=${pduType} li=${li}',
|
|
50
|
+
properties: {
|
|
51
|
+
//Length Indicator: the count of header octets following this byte (excludes LI + data).
|
|
52
|
+
//Honoured when supplied; else derived from the PDU Type + any verbatim header bytes.
|
|
53
|
+
li: {
|
|
54
|
+
type: 'integer',
|
|
55
|
+
label: 'Length Indicator',
|
|
56
|
+
minimum: 0,
|
|
57
|
+
maximum: 255,
|
|
58
|
+
decode: function () {
|
|
59
|
+
this.instance.li.setValue((0, BufferToNumber_1.BufferToUInt8)(this.readBytes(0, 1)));
|
|
60
|
+
},
|
|
61
|
+
encode: function () {
|
|
62
|
+
const provided = this.instance.li.getValue(0);
|
|
63
|
+
let value = provided;
|
|
64
|
+
if (!value) {
|
|
65
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
66
|
+
const headerRest = (0, HexToBuffer_1.HexToBuffer)(this.instance.headerRest.getValue(''));
|
|
67
|
+
//pduType(1) + (DT ? the EOT/TPDU-NR octet(1) : 0) + verbatim header bytes.
|
|
68
|
+
value = 1 + (dt ? 1 : 0) + headerRest.length;
|
|
69
|
+
}
|
|
70
|
+
if (value > 255) {
|
|
71
|
+
this.recordError(this.instance.li.getPath(), 'Maximum value is 255');
|
|
72
|
+
value = 255;
|
|
73
|
+
}
|
|
74
|
+
this.instance.li.setValue(value);
|
|
75
|
+
this.writeBytes(0, (0, NumberToBuffer_1.UInt8ToBuffer)(value));
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
//Full PDU Type octet (high nibble = type code, low nibble kept verbatim), e.g. DT = 0xF0 = 240.
|
|
79
|
+
pduType: this.fieldUInt('pduType', 1, 1, 'PDU Type'),
|
|
80
|
+
//DT only: bit 7 of the octet at offset 2 — "end of TSDU". Meaningless for other types (left false).
|
|
81
|
+
eot: {
|
|
82
|
+
type: 'boolean',
|
|
83
|
+
label: 'EOT',
|
|
84
|
+
decode: function () {
|
|
85
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
86
|
+
this.instance.eot.setValue(dt ? !!this.readBits(2, 1, 0, 1) : false);
|
|
87
|
+
},
|
|
88
|
+
encode: function () {
|
|
89
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
90
|
+
if (dt)
|
|
91
|
+
this.writeBits(2, 1, 0, 1, this.instance.eot.getValue(false) ? 1 : 0);
|
|
92
|
+
}
|
|
93
|
+
},
|
|
94
|
+
//DT only: the low 7 bits of the octet at offset 2 — the TPDU sequence number.
|
|
95
|
+
tpduNr: {
|
|
96
|
+
type: 'integer',
|
|
97
|
+
label: 'TPDU Number',
|
|
98
|
+
minimum: 0,
|
|
99
|
+
maximum: 127,
|
|
100
|
+
decode: function () {
|
|
101
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
102
|
+
this.instance.tpduNr.setValue(dt ? this.readBits(2, 1, 1, 7) : 0);
|
|
103
|
+
},
|
|
104
|
+
encode: function () {
|
|
105
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
106
|
+
if (dt)
|
|
107
|
+
this.writeBits(2, 1, 1, 7, this.instance.tpduNr.getValue(0));
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
//The type-specific header bytes of a non-DT TPDU (CR/CC/DR/ER/…), bounded by LI and kept
|
|
111
|
+
//verbatim so every TPDU variant round-trips byte-for-byte. Empty for a DT TPDU (its single
|
|
112
|
+
//type-specific octet is structured into eot/tpduNr above).
|
|
113
|
+
headerRest: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
label: 'Header Rest',
|
|
116
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
117
|
+
decode: function () {
|
|
118
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
119
|
+
const li = this.instance.li.getValue(0);
|
|
120
|
+
const available = this.packet.length - this.startPos;
|
|
121
|
+
//The COTP header occupies octets [0, 1 + li); clamp to the captured bytes.
|
|
122
|
+
let headerEnd = 1 + li;
|
|
123
|
+
if (headerEnd > available)
|
|
124
|
+
headerEnd = available;
|
|
125
|
+
const restStart = dt ? 3 : 2;
|
|
126
|
+
this.instance.headerRest.setValue(headerEnd > restStart ? (0, BufferToHex_1.BufferToHex)(this.readBytes(restStart, headerEnd - restStart)) : '');
|
|
127
|
+
},
|
|
128
|
+
encode: function () {
|
|
129
|
+
const dt = COTP.#isDT(this.instance.pduType.getValue(0));
|
|
130
|
+
const headerRest = this.instance.headerRest.getValue('');
|
|
131
|
+
if (headerRest)
|
|
132
|
+
this.writeBytes(dt ? 3 : 2, (0, HexToBuffer_1.HexToBuffer)(headerRest));
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
//The user data (ISO Session / Presentation / ACSE / MMS bytes), kept verbatim. Bounded by
|
|
136
|
+
//the parent TPKT's Length when available (so trailing bytes are not absorbed), else runs to
|
|
137
|
+
//the end of the captured bytes.
|
|
138
|
+
data: {
|
|
139
|
+
type: 'string',
|
|
140
|
+
label: 'Data',
|
|
141
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
142
|
+
decode: function () {
|
|
143
|
+
const li = this.instance.li.getValue(0);
|
|
144
|
+
const available = this.packet.length - this.startPos;
|
|
145
|
+
const dataStart = 1 + li;
|
|
146
|
+
//Expose the user data as a dispatchable CHILD layer (RDP / S7comm / ISO-Session /
|
|
147
|
+
//MMS) instead of consuming it here, but ONLY when the upper PDU is fully self-
|
|
148
|
+
//contained in this packet: a DT TPDU with EOT set, riding on TPKT, whose TPKT-
|
|
149
|
+
//declared length exactly equals the captured remaining bytes. That rules out
|
|
150
|
+
//fragmentation (EOT=0, which a single-packet stateless codec cannot reassemble),
|
|
151
|
+
//truncation, and a pipelined trailing TPKT PDU (which an unbounded RawData child
|
|
152
|
+
//would otherwise swallow). In that case set data='' and return WITHOUT reading, so
|
|
153
|
+
//headerLength stops at the header end and the codec dispatches the remaining bytes.
|
|
154
|
+
const pduType = this.instance.pduType.getValue(0);
|
|
155
|
+
const dt = COTP.#isDT(pduType);
|
|
156
|
+
const eot = this.instance.eot.getValue(false);
|
|
157
|
+
//A DT with EOT set, or a Connection Request (0xE0) / Connection Confirm (0xD0)
|
|
158
|
+
//whose user data (an RDP Negotiation Request/Response) is single-PDU by nature.
|
|
159
|
+
const exposeChild = (dt && eot) || pduType === 0xe0 || pduType === 0xd0;
|
|
160
|
+
if (exposeChild && this.prevCodecModule && this.prevCodecModule.id === 'tpkt') {
|
|
161
|
+
const cotpPdu = this.prevCodecModule.instance.length.getValue(0) - 4;
|
|
162
|
+
if (cotpPdu === available && available > dataStart) {
|
|
163
|
+
this.instance.data.setValue('');
|
|
164
|
+
return;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
//Otherwise COTP remains a leaf and keeps the user data verbatim, bounded by the TPKT
|
|
168
|
+
//Length so a pipelined trailing PDU is left for a fresh TPKT dispatch.
|
|
169
|
+
let end = available;
|
|
170
|
+
if (this.prevCodecModule && this.prevCodecModule.id === 'tpkt') {
|
|
171
|
+
const cotpPdu = this.prevCodecModule.instance.length.getValue(0) - 4;
|
|
172
|
+
if (cotpPdu >= 0 && cotpPdu < end)
|
|
173
|
+
end = cotpPdu;
|
|
174
|
+
}
|
|
175
|
+
this.instance.data.setValue(end > dataStart ? (0, BufferToHex_1.BufferToHex)(this.readBytes(dataStart, end - dataStart)) : '');
|
|
176
|
+
},
|
|
177
|
+
encode: function () {
|
|
178
|
+
const li = this.instance.li.getValue(0);
|
|
179
|
+
const data = this.instance.data.getValue('');
|
|
180
|
+
if (data)
|
|
181
|
+
this.writeBytes(1 + li, (0, HexToBuffer_1.HexToBuffer)(data));
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
match() {
|
|
188
|
+
//COTP is carried exclusively inside a TPKT PDU — gate purely on the parent being TPKT so a stray
|
|
189
|
+
//TCP payload is never mis-claimed (the heuristic chain offers COTP on every layer).
|
|
190
|
+
return !!this.prevCodecModule && this.prevCodecModule.id === 'tpkt';
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
exports.COTP = COTP;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* Cassandra CQL native protocol (DataStax/Apache Cassandra, native protocol v4), TCP port 9042. Every
|
|
6
|
+
* CQL frame begins with a fixed 9-byte big-endian header — Version (the direction bit 0x80 OR-ed with
|
|
7
|
+
* the protocol version, so 0x04 = a v4 request, 0x84 = a v4 response), Flags, a 2-byte Stream id, an
|
|
8
|
+
* Opcode (0x01 STARTUP, 0x02 READY, 0x05 OPTIONS, 0x07 QUERY, 0x08 RESULT, 0x09 PREPARE, …), and a
|
|
9
|
+
* 4-byte Length (the octet count of the body that follows) — followed by `Length` bytes of
|
|
10
|
+
* opcode-specific body.
|
|
11
|
+
*
|
|
12
|
+
* The body layout differs per opcode (STARTUP's [string map], QUERY's query + consistency, RESULT's
|
|
13
|
+
* kind + rows metadata, …) and several bodies need query-prepare / paging context, so this
|
|
14
|
+
* single-frame codec keeps the body verbatim as `body` hex (byte-perfect) and does not sub-decode it.
|
|
15
|
+
* The Length is auto-computed from the body on encode when not supplied, else honored verbatim (a
|
|
16
|
+
* crafted frame may lie); the body is bounded by the Length so a second pipelined CQL frame or trailing
|
|
17
|
+
* bytes are left to the codec's recursion / RawData. A well-formed frame round-trips byte-for-byte.
|
|
18
|
+
*/
|
|
19
|
+
export declare class CassandraCQL extends BaseHeader {
|
|
20
|
+
#private;
|
|
21
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
22
|
+
readonly id: string;
|
|
23
|
+
readonly name: string;
|
|
24
|
+
readonly nickname: string;
|
|
25
|
+
readonly matchKeys: string[];
|
|
26
|
+
match(): boolean;
|
|
27
|
+
readonly demuxProducers: DemuxProducer[];
|
|
28
|
+
}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CassandraCQL = void 0;
|
|
4
|
+
const BaseHeader_1 = require("../abstracts/BaseHeader");
|
|
5
|
+
const BufferToHex_1 = require("../helper/BufferToHex");
|
|
6
|
+
const HexToBuffer_1 = require("../helper/HexToBuffer");
|
|
7
|
+
const BufferToNumber_1 = require("../helper/BufferToNumber");
|
|
8
|
+
const NumberToBuffer_1 = require("../helper/NumberToBuffer");
|
|
9
|
+
const StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
|
|
10
|
+
/**
|
|
11
|
+
* Cassandra CQL native protocol (DataStax/Apache Cassandra, native protocol v4), TCP port 9042. Every
|
|
12
|
+
* CQL frame begins with a fixed 9-byte big-endian header — Version (the direction bit 0x80 OR-ed with
|
|
13
|
+
* the protocol version, so 0x04 = a v4 request, 0x84 = a v4 response), Flags, a 2-byte Stream id, an
|
|
14
|
+
* Opcode (0x01 STARTUP, 0x02 READY, 0x05 OPTIONS, 0x07 QUERY, 0x08 RESULT, 0x09 PREPARE, …), and a
|
|
15
|
+
* 4-byte Length (the octet count of the body that follows) — followed by `Length` bytes of
|
|
16
|
+
* opcode-specific body.
|
|
17
|
+
*
|
|
18
|
+
* The body layout differs per opcode (STARTUP's [string map], QUERY's query + consistency, RESULT's
|
|
19
|
+
* kind + rows metadata, …) and several bodies need query-prepare / paging context, so this
|
|
20
|
+
* single-frame codec keeps the body verbatim as `body` hex (byte-perfect) and does not sub-decode it.
|
|
21
|
+
* The Length is auto-computed from the body on encode when not supplied, else honored verbatim (a
|
|
22
|
+
* crafted frame may lie); the body is bounded by the Length so a second pipelined CQL frame or trailing
|
|
23
|
+
* bytes are left to the codec's recursion / RawData. A well-formed frame round-trips byte-for-byte.
|
|
24
|
+
*/
|
|
25
|
+
class CassandraCQL extends BaseHeader_1.BaseHeader {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
this.id = 'cql';
|
|
29
|
+
this.name = 'Cassandra CQL';
|
|
30
|
+
this.nickname = 'CQL';
|
|
31
|
+
this.matchKeys = ['tcpport:9042'];
|
|
32
|
+
//A leaf header — the opcode-specific body requires per-opcode, cross-frame parsing.
|
|
33
|
+
this.demuxProducers = [];
|
|
34
|
+
}
|
|
35
|
+
static #schemaCache;
|
|
36
|
+
get SCHEMA() {
|
|
37
|
+
return (CassandraCQL.#schemaCache ??= CassandraCQL.#buildSchema());
|
|
38
|
+
}
|
|
39
|
+
static #buildSchema() {
|
|
40
|
+
return {
|
|
41
|
+
type: 'object',
|
|
42
|
+
summary: 'CQL v=${version} opcode=${opcode} len=${length}',
|
|
43
|
+
properties: {
|
|
44
|
+
//Version octet: direction bit 0x80 (request 0, response 1) OR-ed with the protocol
|
|
45
|
+
//version in the low 7 bits (e.g. 0x04 v4 request, 0x84 v4 response). Kept as the full
|
|
46
|
+
//octet so both the direction bit and the version round-trip; the split is UI enrichment.
|
|
47
|
+
version: this.fieldUInt('version', 0, 1, 'Version'),
|
|
48
|
+
//Frame flags (bit 0 compression, bit 1 tracing, bit 2 custom payload, bit 3 warning).
|
|
49
|
+
flags: this.fieldUInt('flags', 1, 1, 'Flags'),
|
|
50
|
+
//Stream id correlating requests with responses (may be negative on the wire for
|
|
51
|
+
//server-initiated events; kept as a plain 2-byte value — byte-perfect and editable).
|
|
52
|
+
stream: this.fieldUInt('stream', 2, 2, 'Stream'),
|
|
53
|
+
//Opcode naming the message (0x01 STARTUP, 0x02 READY, 0x05 OPTIONS, 0x07 QUERY,
|
|
54
|
+
//0x08 RESULT, 0x09 PREPARE, …). Plain uint8 so any opcode round-trips.
|
|
55
|
+
opcode: this.fieldUInt('opcode', 4, 1, 'Opcode'),
|
|
56
|
+
length: {
|
|
57
|
+
type: 'integer',
|
|
58
|
+
label: 'Length',
|
|
59
|
+
minimum: 0,
|
|
60
|
+
maximum: 4294967295,
|
|
61
|
+
decode: function () {
|
|
62
|
+
this.instance.length.setValue((0, BufferToNumber_1.BufferToUInt32)(this.readBytes(5, 4)));
|
|
63
|
+
},
|
|
64
|
+
encode: function () {
|
|
65
|
+
//Length counts only the body that follows the 9-byte header. Honored when supplied
|
|
66
|
+
//(a crafted frame may lie); else derived from the body.
|
|
67
|
+
const provided = this.instance.length.getValue();
|
|
68
|
+
let value = (provided !== undefined && provided !== null)
|
|
69
|
+
? provided
|
|
70
|
+
: (0, HexToBuffer_1.HexToBuffer)(this.instance.body.getValue('')).length;
|
|
71
|
+
if (value > 4294967295) {
|
|
72
|
+
this.recordError(this.instance.length.getPath(), 'Maximum value is 4294967295');
|
|
73
|
+
value = 4294967295;
|
|
74
|
+
}
|
|
75
|
+
if (value < 0) {
|
|
76
|
+
this.recordError(this.instance.length.getPath(), 'Minimum value is 0');
|
|
77
|
+
value = 0;
|
|
78
|
+
}
|
|
79
|
+
this.instance.length.setValue(value);
|
|
80
|
+
this.writeBytes(5, (0, NumberToBuffer_1.UInt32ToBuffer)(value));
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
//The opcode-specific body after the 9-byte header, kept verbatim. Bounded by the Length
|
|
84
|
+
//field (the body ends at offset 9 + Length) and the captured bytes, so trailing /
|
|
85
|
+
//pipelined data is left to the codec's recursion / RawData.
|
|
86
|
+
body: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
label: 'Body',
|
|
89
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
90
|
+
decode: function () {
|
|
91
|
+
const remaining = this.packet.length - this.startPos;
|
|
92
|
+
const length = this.instance.length.getValue(0);
|
|
93
|
+
let end = 9 + length;
|
|
94
|
+
if (end > remaining)
|
|
95
|
+
end = remaining;
|
|
96
|
+
this.instance.body.setValue(end > 9 ? (0, BufferToHex_1.BufferToHex)(this.readBytes(9, end - 9)) : '');
|
|
97
|
+
},
|
|
98
|
+
encode: function () {
|
|
99
|
+
const body = this.instance.body.getValue('');
|
|
100
|
+
if (body)
|
|
101
|
+
this.writeBytes(9, (0, HexToBuffer_1.HexToBuffer)(body));
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
match() {
|
|
108
|
+
//Cassandra CQL rides on TCP port 9042. The 9-byte header carries no strong content magic (the
|
|
109
|
+
//version octet's low nibble is just a small protocol version), so the well-known port is the
|
|
110
|
+
//signature: require the previous layer to be TCP and the full 9-byte header to be present. Stays
|
|
111
|
+
//port-bucketed (matchKeys only, no heuristicFallback) so non-CQL 9042 traffic falls through to raw.
|
|
112
|
+
if (!this.prevCodecModule || this.prevCodecModule.id !== 'tcp')
|
|
113
|
+
return false;
|
|
114
|
+
return this.packet.length - this.startPos >= 9;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
exports.CassandraCQL = CassandraCQL;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* CoAP — Constrained Application Protocol (RFC 7252), a RESTful transfer protocol for constrained nodes
|
|
6
|
+
* and networks (IoT), riding on UDP port 5683. Every message opens with a 4-byte fixed header: byte 0
|
|
7
|
+
* holds the 2-bit Version (always 1), a 2-bit Type (0 CON, 1 NON, 2 ACK, 3 RST) and a 4-bit Token
|
|
8
|
+
* Length (TKL, 0-8); byte 1 is the 8-bit Code (a 3-bit class '.' 5-bit detail, e.g. 0.01 GET = 0x01,
|
|
9
|
+
* 2.05 Content = 0x45); bytes 2-3 are the big-endian Message ID. The fixed header is followed by a
|
|
10
|
+
* Token of TKL octets, then a sequence of Options, then optionally a 0xFF payload marker and the
|
|
11
|
+
* payload.
|
|
12
|
+
*
|
|
13
|
+
* This codec decodes the fixed header and the Token structurally and keeps everything after the Token
|
|
14
|
+
* (the Options plus the optional payload-marker-and-payload) verbatim as `payload` hex — de-structuring
|
|
15
|
+
* CoAP's option deltas / TLV encoding is a later slice, so those bytes are preserved untouched and the
|
|
16
|
+
* message round-trips byte-for-byte. The region is bounded by the UDP datagram length so any trailing
|
|
17
|
+
* padding is not absorbed. version === 1 is the content signature that separates a real CoAP datagram
|
|
18
|
+
* on port 5683 from arbitrary traffic.
|
|
19
|
+
*/
|
|
20
|
+
export declare class CoAP extends BaseHeader {
|
|
21
|
+
#private;
|
|
22
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
23
|
+
readonly id: string;
|
|
24
|
+
readonly name: string;
|
|
25
|
+
readonly nickname: string;
|
|
26
|
+
readonly matchKeys: string[];
|
|
27
|
+
match(): boolean;
|
|
28
|
+
readonly demuxProducers: DemuxProducer[];
|
|
29
|
+
}
|