@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,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.S7comm = 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
|
+
* S7comm — the Siemens S7 Communication protocol (S7-300/400/1200/1500 PLC), the application layer of
|
|
12
|
+
* the S7 ISO-on-TCP stack: it rides inside a COTP DT (Data) TPDU, itself carried by a TPKT PDU on TCP
|
|
13
|
+
* port 102 (RFC 1006). Every S7comm PDU begins with a fixed 10-byte header — a Protocol Id (always
|
|
14
|
+
* 0x32), a ROSCTR (message class: 1 Job request, 2 Ack, 3 Ack_Data, 7 Userdata), a 2-byte Redundancy
|
|
15
|
+
* Identification (reserved, normally 0), a 2-byte PDU Reference, and the 2-byte Parameter Length and
|
|
16
|
+
* Data Length that delimit the two variable sections — plus, ONLY for the Ack / Ack_Data classes
|
|
17
|
+
* (ROSCTR 2 or 3), a 2-byte error field (Error Class + Error Code). The Parameter section (the S7
|
|
18
|
+
* function + its arguments) and the Data section (item values, results) then follow, sized by the two
|
|
19
|
+
* length fields.
|
|
20
|
+
*
|
|
21
|
+
* The Parameter and Data sections are function-dependent, cross-PDU state (Setup Communication,
|
|
22
|
+
* Read/Write Var, block up/download, PLC control, …), so this codec keeps them verbatim as bounded hex
|
|
23
|
+
* (byte-perfect): `parameter` sized by Parameter Length and `data` sized by Data Length. The two length
|
|
24
|
+
* fields are honor-else-derive (honored verbatim when supplied — a crafted PDU may lie — else derived
|
|
25
|
+
* from the hex byte length of their section). Every field is BIG-ENDIAN (S7comm is not CIP/ENIP). A
|
|
26
|
+
* well-formed PDU round-trips byte-for-byte.
|
|
27
|
+
*
|
|
28
|
+
* S7comm is gated purely on its parent being a COTP DT TPDU (prev.id === 'cotp') plus the Protocol Id
|
|
29
|
+
* 0x32 signature at offset 0 (heuristicFallback), mirroring how COTP itself is an unkeyed
|
|
30
|
+
* content-heuristic child of TPKT — nothing on TCP/102 other than a COTP-carried 0x32 PDU is S7comm.
|
|
31
|
+
*/
|
|
32
|
+
class S7comm extends BaseHeader_1.BaseHeader {
|
|
33
|
+
constructor() {
|
|
34
|
+
super(...arguments);
|
|
35
|
+
this.id = 's7comm';
|
|
36
|
+
this.name = 'S7 Communication';
|
|
37
|
+
this.nickname = 'S7comm';
|
|
38
|
+
//S7comm rides on TCP port 102, but always inside a COTP DT TPDU. Like COTP (which demuxes off TPKT
|
|
39
|
+
//with no matchKeys), selection is by content: heuristicFallback lists it in the heuristic chain and
|
|
40
|
+
//match() gates on the COTP parent plus the 0x32 signature.
|
|
41
|
+
this.matchKeys = [];
|
|
42
|
+
this.heuristicFallback = true;
|
|
43
|
+
//A leaf for now — the Parameter/Data sections require per-function, cross-PDU parsing.
|
|
44
|
+
this.demuxProducers = [];
|
|
45
|
+
}
|
|
46
|
+
static #schemaCache;
|
|
47
|
+
get SCHEMA() {
|
|
48
|
+
return (S7comm.#schemaCache ??= S7comm.#buildSchema());
|
|
49
|
+
}
|
|
50
|
+
/** The 2-byte error field (Error Class + Error Code) is present ONLY on Ack (2) / Ack_Data (3). */
|
|
51
|
+
static #hasError(rosctr) {
|
|
52
|
+
return rosctr === 2 || rosctr === 3;
|
|
53
|
+
}
|
|
54
|
+
/** Length of the fixed header: 10 bytes, plus the 2-byte error field on Ack / Ack_Data. */
|
|
55
|
+
static #headerLen(rosctr) {
|
|
56
|
+
return 10 + (S7comm.#hasError(rosctr) ? 2 : 0);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Absolute byte offset (relative to this header) at which the COTP-delimited S7comm payload ends —
|
|
60
|
+
* i.e. the end of the enclosing TPKT PDU. Used to double-cap the Parameter/Data sections so a lying
|
|
61
|
+
* length field cannot read past the COTP payload into a trailing/pipelined TPKT PDU. Falls back to
|
|
62
|
+
* the captured-bytes end when no bounding TPKT length is available.
|
|
63
|
+
*/
|
|
64
|
+
#payloadEnd() {
|
|
65
|
+
let end = this.packet.length - this.startPos;
|
|
66
|
+
for (const codecModule of this.prevCodecModules) {
|
|
67
|
+
if (codecModule.id === 'tpkt') {
|
|
68
|
+
//TPKT Length spans the whole TPKT PDU (its 4-byte header included); its absolute end is
|
|
69
|
+
//the end of everything COTP carries, hence the end of this S7comm PDU.
|
|
70
|
+
const tpktLength = codecModule.instance.length.getValue(0);
|
|
71
|
+
const relEnd = codecModule.startPos + tpktLength - this.startPos;
|
|
72
|
+
if (relEnd >= 0 && relEnd < end)
|
|
73
|
+
end = relEnd;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
return end;
|
|
77
|
+
}
|
|
78
|
+
/** honor-else-derive length field: honored verbatim when supplied, else derived from `sectionName`. */
|
|
79
|
+
static #lengthField(name, offset, sectionName, label) {
|
|
80
|
+
return {
|
|
81
|
+
type: 'integer',
|
|
82
|
+
label: label,
|
|
83
|
+
minimum: 0,
|
|
84
|
+
maximum: 65535,
|
|
85
|
+
decode: function () {
|
|
86
|
+
this.instance[name].setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(offset, 2)));
|
|
87
|
+
},
|
|
88
|
+
encode: function () {
|
|
89
|
+
const node = this.instance[name];
|
|
90
|
+
const provided = node.getValue();
|
|
91
|
+
let value = (provided !== undefined && provided !== null)
|
|
92
|
+
? provided
|
|
93
|
+
: (0, HexToBuffer_1.HexToBuffer)(this.instance[sectionName].getValue('')).length;
|
|
94
|
+
if (value > 65535) {
|
|
95
|
+
this.recordError(node.getPath(), 'Maximum value is 65535');
|
|
96
|
+
value = 65535;
|
|
97
|
+
}
|
|
98
|
+
if (value < 0) {
|
|
99
|
+
this.recordError(node.getPath(), 'Minimum value is 0');
|
|
100
|
+
value = 0;
|
|
101
|
+
}
|
|
102
|
+
node.setValue(value);
|
|
103
|
+
this.writeBytes(offset, (0, NumberToBuffer_1.UInt16ToBuffer)(value));
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
static #buildSchema() {
|
|
108
|
+
return {
|
|
109
|
+
type: 'object',
|
|
110
|
+
summary: 'S7comm rosctr=${rosctr} ref=${pduReference}',
|
|
111
|
+
properties: {
|
|
112
|
+
//Protocol Id: always 0x32 for S7comm. A plain uint (no enum) so a crafted/off-spec value
|
|
113
|
+
//still round-trips; the 0x32 signature gates selection in match(), not the schema.
|
|
114
|
+
protocolId: this.fieldUInt('protocolId', 0, 1, 'Protocol Id'),
|
|
115
|
+
//ROSCTR (message class): 1 Job, 2 Ack, 3 Ack_Data, 7 Userdata. Kept as a plain uint —
|
|
116
|
+
//an unknown class must still decode and re-encode, so no enum constraint is applied.
|
|
117
|
+
rosctr: this.fieldUInt('rosctr', 1, 1, 'ROSCTR'),
|
|
118
|
+
//Redundancy Identification: reserved, normally 0x0000. Kept verbatim so any value round-trips.
|
|
119
|
+
redundancyId: this.fieldHex('redundancyId', 2, 2, 'Redundancy Identification'),
|
|
120
|
+
pduReference: this.fieldUInt('pduReference', 4, 2, 'PDU Reference'),
|
|
121
|
+
//Parameter Length / Data Length delimit the two variable sections. honor-else-derive.
|
|
122
|
+
parameterLength: this.#lengthField('parameterLength', 6, 'parameter', 'Parameter Length'),
|
|
123
|
+
dataLength: this.#lengthField('dataLength', 8, 'data', 'Data Length'),
|
|
124
|
+
//Error Class + Error Code: present ONLY on Ack (2) / Ack_Data (3) — bytes 10..11. For a
|
|
125
|
+
//Job (1) / Userdata (7) PDU these octets do not exist, so decode leaves them 0 and encode
|
|
126
|
+
//writes nothing (mirrors COTP's DT-only eot/tpduNr conditional fields).
|
|
127
|
+
errorClass: {
|
|
128
|
+
type: 'integer',
|
|
129
|
+
label: 'Error Class',
|
|
130
|
+
minimum: 0,
|
|
131
|
+
maximum: 255,
|
|
132
|
+
decode: function () {
|
|
133
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
134
|
+
this.instance.errorClass.setValue(S7comm.#hasError(rosctr) ? this.readBytes(10, 1)[0] : 0);
|
|
135
|
+
},
|
|
136
|
+
encode: function () {
|
|
137
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
138
|
+
if (!S7comm.#hasError(rosctr))
|
|
139
|
+
return;
|
|
140
|
+
let value = this.instance.errorClass.getValue(0);
|
|
141
|
+
if (value > 255) {
|
|
142
|
+
this.recordError(this.instance.errorClass.getPath(), 'Maximum value is 255');
|
|
143
|
+
value = 255;
|
|
144
|
+
}
|
|
145
|
+
if (value < 0) {
|
|
146
|
+
this.recordError(this.instance.errorClass.getPath(), 'Minimum value is 0');
|
|
147
|
+
value = 0;
|
|
148
|
+
}
|
|
149
|
+
this.instance.errorClass.setValue(value);
|
|
150
|
+
this.writeBytes(10, Buffer.from([value & 0xff]));
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
errorCode: {
|
|
154
|
+
type: 'integer',
|
|
155
|
+
label: 'Error Code',
|
|
156
|
+
minimum: 0,
|
|
157
|
+
maximum: 255,
|
|
158
|
+
decode: function () {
|
|
159
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
160
|
+
this.instance.errorCode.setValue(S7comm.#hasError(rosctr) ? this.readBytes(11, 1)[0] : 0);
|
|
161
|
+
},
|
|
162
|
+
encode: function () {
|
|
163
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
164
|
+
if (!S7comm.#hasError(rosctr))
|
|
165
|
+
return;
|
|
166
|
+
let value = this.instance.errorCode.getValue(0);
|
|
167
|
+
if (value > 255) {
|
|
168
|
+
this.recordError(this.instance.errorCode.getPath(), 'Maximum value is 255');
|
|
169
|
+
value = 255;
|
|
170
|
+
}
|
|
171
|
+
if (value < 0) {
|
|
172
|
+
this.recordError(this.instance.errorCode.getPath(), 'Minimum value is 0');
|
|
173
|
+
value = 0;
|
|
174
|
+
}
|
|
175
|
+
this.instance.errorCode.setValue(value);
|
|
176
|
+
this.writeBytes(11, Buffer.from([value & 0xff]));
|
|
177
|
+
}
|
|
178
|
+
},
|
|
179
|
+
//Parameter section (S7 function + arguments), kept verbatim. Sized by Parameter Length,
|
|
180
|
+
//double-capped by the COTP-delimited payload end so a lying length cannot swallow the
|
|
181
|
+
//Data section or a trailing TPKT PDU.
|
|
182
|
+
parameter: {
|
|
183
|
+
type: 'string',
|
|
184
|
+
label: 'Parameter',
|
|
185
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
186
|
+
decode: function () {
|
|
187
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
188
|
+
const headerLen = S7comm.#headerLen(rosctr);
|
|
189
|
+
const parameterLength = this.instance.parameterLength.getValue(0);
|
|
190
|
+
let end = headerLen + parameterLength;
|
|
191
|
+
const payloadEnd = this.#payloadEnd();
|
|
192
|
+
if (end > payloadEnd)
|
|
193
|
+
end = payloadEnd;
|
|
194
|
+
this.instance.parameter.setValue(end > headerLen ? (0, BufferToHex_1.BufferToHex)(this.readBytes(headerLen, end - headerLen)) : '');
|
|
195
|
+
},
|
|
196
|
+
encode: function () {
|
|
197
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
198
|
+
const headerLen = S7comm.#headerLen(rosctr);
|
|
199
|
+
const parameter = this.instance.parameter.getValue('');
|
|
200
|
+
if (parameter)
|
|
201
|
+
this.writeBytes(headerLen, (0, HexToBuffer_1.HexToBuffer)(parameter));
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
//Data section (item values / results), kept verbatim. Sized by Data Length, double-capped
|
|
205
|
+
//by the COTP-delimited payload end (so trailing/pipelined bytes fall through to the codec).
|
|
206
|
+
data: {
|
|
207
|
+
type: 'string',
|
|
208
|
+
label: 'Data',
|
|
209
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
210
|
+
decode: function () {
|
|
211
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
212
|
+
const headerLen = S7comm.#headerLen(rosctr);
|
|
213
|
+
const parameterLength = this.instance.parameterLength.getValue(0);
|
|
214
|
+
const dataLength = this.instance.dataLength.getValue(0);
|
|
215
|
+
const dataStart = headerLen + parameterLength;
|
|
216
|
+
let end = dataStart + dataLength;
|
|
217
|
+
const payloadEnd = this.#payloadEnd();
|
|
218
|
+
if (end > payloadEnd)
|
|
219
|
+
end = payloadEnd;
|
|
220
|
+
this.instance.data.setValue(end > dataStart ? (0, BufferToHex_1.BufferToHex)(this.readBytes(dataStart, end - dataStart)) : '');
|
|
221
|
+
},
|
|
222
|
+
encode: function () {
|
|
223
|
+
const rosctr = this.instance.rosctr.getValue(0);
|
|
224
|
+
const headerLen = S7comm.#headerLen(rosctr);
|
|
225
|
+
const parameterLength = this.instance.parameterLength.getValue(0);
|
|
226
|
+
const data = this.instance.data.getValue('');
|
|
227
|
+
if (data)
|
|
228
|
+
this.writeBytes(headerLen + parameterLength, (0, HexToBuffer_1.HexToBuffer)(data));
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
match() {
|
|
235
|
+
//S7comm is carried exclusively inside a COTP DT TPDU — gate on the parent being COTP so a stray
|
|
236
|
+
//TCP/102 payload is never mis-claimed, then confirm the Protocol Id 0x32 signature at offset 0.
|
|
237
|
+
if (!this.prevCodecModule || this.prevCodecModule.id !== 'cotp')
|
|
238
|
+
return false;
|
|
239
|
+
if (this.packet.length - this.startPos < 1)
|
|
240
|
+
return false;
|
|
241
|
+
return this.readBytes(0, 1, true)[0] === 0x32;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
exports.S7comm = S7comm;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* SCTP — Stream Control Transmission Protocol (RFC 9260), carried directly over IP as protocol 132
|
|
6
|
+
* (both IPv4 `protocol` and IPv6 `nxt`). The 12-byte common header is all big-endian: Source Port (2) +
|
|
7
|
+
* Destination Port (2) + Verification Tag (4) + Checksum (4). The Checksum is a CRC32c over the whole
|
|
8
|
+
* SCTP packet (with the field zeroed) stored little-endian on the wire — but it is honored verbatim,
|
|
9
|
+
* never recomputed (encode is a faithful executor), so it is surfaced as an opaque 4-byte hex string.
|
|
10
|
+
*
|
|
11
|
+
* After the common header comes a chain of chunks until the enclosing IP payload is consumed. Each chunk
|
|
12
|
+
* is Type(1) + Flags(1) + Length(2) + Value, where Length counts the 4-byte chunk header plus the value
|
|
13
|
+
* but NOT the trailing padding to the next 4-byte boundary. Because the Length excludes that pad, the
|
|
14
|
+
* alignment padding (0..3 bytes) is the tricky part of a byte-perfect round-trip: it is captured verbatim
|
|
15
|
+
* (per chunk, as hex) and re-emitted, so even a malformed non-zero pad reproduces exactly. Chunks are
|
|
16
|
+
* carried generically (type + flags + verbatim hex value) so every chunk type — DATA(0), INIT(1),
|
|
17
|
+
* INIT_ACK(2), SACK(3), HEARTBEAT(4), HEARTBEAT_ACK(5), COOKIE_ECHO(10), COOKIE_ACK(11), … — round-trips;
|
|
18
|
+
* per-chunk semantic decoding (and cross-packet DATA reassembly) is a later enrichment.
|
|
19
|
+
*
|
|
20
|
+
* The chunk walk is bounded by the enclosing IP datagram, so a lying chunk Length near the end does not
|
|
21
|
+
* read into a trailing Ethernet FCS; a chunk whose Length overruns the available bytes (or is below its
|
|
22
|
+
* own 4-byte header) stops the walk, leaving the remainder to the codec's recursion / RawData. A
|
|
23
|
+
* well-formed SCTP packet round-trips byte-for-byte. This is a single-packet codec: chunks are dissected
|
|
24
|
+
* in place, with no cross-packet reassembly.
|
|
25
|
+
*/
|
|
26
|
+
export declare class SCTP extends BaseHeader {
|
|
27
|
+
#private;
|
|
28
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
29
|
+
readonly id: string;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly nickname: string;
|
|
32
|
+
readonly matchKeys: string[];
|
|
33
|
+
match(): boolean;
|
|
34
|
+
readonly demuxProducers: DemuxProducer[];
|
|
35
|
+
}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SCTP = 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
|
+
* SCTP — Stream Control Transmission Protocol (RFC 9260), carried directly over IP as protocol 132
|
|
12
|
+
* (both IPv4 `protocol` and IPv6 `nxt`). The 12-byte common header is all big-endian: Source Port (2) +
|
|
13
|
+
* Destination Port (2) + Verification Tag (4) + Checksum (4). The Checksum is a CRC32c over the whole
|
|
14
|
+
* SCTP packet (with the field zeroed) stored little-endian on the wire — but it is honored verbatim,
|
|
15
|
+
* never recomputed (encode is a faithful executor), so it is surfaced as an opaque 4-byte hex string.
|
|
16
|
+
*
|
|
17
|
+
* After the common header comes a chain of chunks until the enclosing IP payload is consumed. Each chunk
|
|
18
|
+
* is Type(1) + Flags(1) + Length(2) + Value, where Length counts the 4-byte chunk header plus the value
|
|
19
|
+
* but NOT the trailing padding to the next 4-byte boundary. Because the Length excludes that pad, the
|
|
20
|
+
* alignment padding (0..3 bytes) is the tricky part of a byte-perfect round-trip: it is captured verbatim
|
|
21
|
+
* (per chunk, as hex) and re-emitted, so even a malformed non-zero pad reproduces exactly. Chunks are
|
|
22
|
+
* carried generically (type + flags + verbatim hex value) so every chunk type — DATA(0), INIT(1),
|
|
23
|
+
* INIT_ACK(2), SACK(3), HEARTBEAT(4), HEARTBEAT_ACK(5), COOKIE_ECHO(10), COOKIE_ACK(11), … — round-trips;
|
|
24
|
+
* per-chunk semantic decoding (and cross-packet DATA reassembly) is a later enrichment.
|
|
25
|
+
*
|
|
26
|
+
* The chunk walk is bounded by the enclosing IP datagram, so a lying chunk Length near the end does not
|
|
27
|
+
* read into a trailing Ethernet FCS; a chunk whose Length overruns the available bytes (or is below its
|
|
28
|
+
* own 4-byte header) stops the walk, leaving the remainder to the codec's recursion / RawData. A
|
|
29
|
+
* well-formed SCTP packet round-trips byte-for-byte. This is a single-packet codec: chunks are dissected
|
|
30
|
+
* in place, with no cross-packet reassembly.
|
|
31
|
+
*/
|
|
32
|
+
class SCTP extends BaseHeader_1.BaseHeader {
|
|
33
|
+
constructor() {
|
|
34
|
+
super(...arguments);
|
|
35
|
+
this.id = 'sctp';
|
|
36
|
+
this.name = 'Stream Control Transmission Protocol';
|
|
37
|
+
this.nickname = 'SCTP';
|
|
38
|
+
this.matchKeys = ['ipproto:132'];
|
|
39
|
+
//A leaf header — chunk values are kept as hex, not demuxed further.
|
|
40
|
+
this.demuxProducers = [];
|
|
41
|
+
}
|
|
42
|
+
static #schemaCache;
|
|
43
|
+
get SCHEMA() {
|
|
44
|
+
return (SCTP.#schemaCache ??= SCTP.#buildSchema());
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Bytes available to SCTP within the enclosing IP datagram — so a short IP payload (or a lying chunk
|
|
48
|
+
* Length) does not let the chunk walk read into a trailing Ethernet FCS / padding. Bounds the chunk
|
|
49
|
+
* reads and the match gate.
|
|
50
|
+
*/
|
|
51
|
+
#available() {
|
|
52
|
+
let available = this.packet.length - this.startPos;
|
|
53
|
+
const prev = this.prevCodecModule;
|
|
54
|
+
if (prev && prev.id === 'ipv4') {
|
|
55
|
+
const ipPayload = prev.instance.length.getValue(0) - prev.length;
|
|
56
|
+
if (ipPayload >= 0 && ipPayload < available)
|
|
57
|
+
available = ipPayload;
|
|
58
|
+
}
|
|
59
|
+
else if (prev && prev.id === 'ipv6') {
|
|
60
|
+
const ipPayload = prev.instance.plen.getValue(0);
|
|
61
|
+
if (ipPayload >= 0 && ipPayload < available)
|
|
62
|
+
available = ipPayload;
|
|
63
|
+
}
|
|
64
|
+
return available < 0 ? 0 : available;
|
|
65
|
+
}
|
|
66
|
+
static #buildSchema() {
|
|
67
|
+
return {
|
|
68
|
+
type: 'object',
|
|
69
|
+
summary: 'SCTP ${srcPort}->${dstPort}',
|
|
70
|
+
properties: {
|
|
71
|
+
srcPort: this.fieldUInt('srcPort', 0, 2, 'Source Port'),
|
|
72
|
+
dstPort: this.fieldUInt('dstPort', 2, 2, 'Destination Port'),
|
|
73
|
+
//32-bit association selector; opaque on the wire, kept verbatim as hex.
|
|
74
|
+
verificationTag: this.fieldHex('verificationTag', 4, 4, 'Verification Tag'),
|
|
75
|
+
//CRC32c over the whole packet (little-endian on the wire) — honored verbatim, never
|
|
76
|
+
//recomputed, so it is surfaced as opaque 4-byte hex and round-trips even when crafted/wrong.
|
|
77
|
+
checksum: this.fieldHex('checksum', 8, 4, 'Checksum'),
|
|
78
|
+
chunks: {
|
|
79
|
+
type: 'array',
|
|
80
|
+
label: 'Chunks',
|
|
81
|
+
items: {
|
|
82
|
+
type: 'object',
|
|
83
|
+
label: 'Chunk',
|
|
84
|
+
properties: {
|
|
85
|
+
type: { type: 'integer', label: 'Chunk Type', minimum: 0, maximum: 255 },
|
|
86
|
+
flags: { type: 'integer', label: 'Chunk Flags', minimum: 0, maximum: 255 },
|
|
87
|
+
length: { type: 'integer', label: 'Chunk Length', minimum: 0, maximum: 65535 },
|
|
88
|
+
value: { type: 'string', label: 'Value', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX },
|
|
89
|
+
padding: { type: 'string', label: 'Padding', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX }
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
decode: function () {
|
|
93
|
+
const available = this.#available();
|
|
94
|
+
const chunks = [];
|
|
95
|
+
let offset = 12;
|
|
96
|
+
//Each chunk is type(1) flags(1) length(2) value. A Length below its own 4-byte
|
|
97
|
+
//header is invalid (and would not advance), and a Length that overruns the
|
|
98
|
+
//available bytes is truncated — in both cases stop and leave the remaining bytes
|
|
99
|
+
//to the codec's recursion / raw layer, keeping the round-trip exact.
|
|
100
|
+
while (offset + 4 <= available) {
|
|
101
|
+
const type = (0, BufferToNumber_1.BufferToUInt8)(this.readBytes(offset, 1, true));
|
|
102
|
+
const flags = (0, BufferToNumber_1.BufferToUInt8)(this.readBytes(offset + 1, 1, true));
|
|
103
|
+
const chunkLength = (0, BufferToNumber_1.BufferToUInt16)(this.readBytes(offset + 2, 2, true));
|
|
104
|
+
if (chunkLength < 4 || offset + chunkLength > available)
|
|
105
|
+
break;
|
|
106
|
+
//Padding to the next 4-byte boundary is NOT counted in chunkLength; for a
|
|
107
|
+
//well-formed packet it is within `available` (clamped defensively otherwise).
|
|
108
|
+
const padLength = (4 - (chunkLength % 4)) % 4;
|
|
109
|
+
const padAvailable = Math.min(padLength, available - (offset + chunkLength));
|
|
110
|
+
const valueLength = chunkLength - 4;
|
|
111
|
+
chunks.push({
|
|
112
|
+
type: type,
|
|
113
|
+
flags: flags,
|
|
114
|
+
length: chunkLength,
|
|
115
|
+
value: valueLength > 0 ? (0, BufferToHex_1.BufferToHex)(this.readBytes(offset + 4, valueLength)) : '',
|
|
116
|
+
padding: padAvailable > 0 ? (0, BufferToHex_1.BufferToHex)(this.readBytes(offset + chunkLength, padAvailable)) : ''
|
|
117
|
+
});
|
|
118
|
+
offset += chunkLength + padAvailable;
|
|
119
|
+
}
|
|
120
|
+
//The chunk-header reads (type/flags/length) are dryRun peeks so a malformed-length
|
|
121
|
+
//break leaves the bytes to trailing RawData; an empty-value chunk (COOKIE_ACK /
|
|
122
|
+
//SHUTDOWN_ACK, Length 4) does no non-dry value/padding read of its own. Mark the
|
|
123
|
+
//whole consumed chunk region with one non-dry read so headerLength covers every
|
|
124
|
+
//byte the walk captured — otherwise a trailing empty chunk is re-decoded as a
|
|
125
|
+
//RawData layer and duplicated on encode (the packet grows and re-encode differs).
|
|
126
|
+
if (offset > 12)
|
|
127
|
+
this.readBytes(12, offset - 12);
|
|
128
|
+
this.instance.chunks.setValue(chunks);
|
|
129
|
+
},
|
|
130
|
+
encode: function () {
|
|
131
|
+
const chunks = this.instance.chunks.getValue([]);
|
|
132
|
+
if (!chunks)
|
|
133
|
+
return;
|
|
134
|
+
let offset = 12;
|
|
135
|
+
for (const chunk of chunks) {
|
|
136
|
+
const type = chunk.type ? chunk.type : 0;
|
|
137
|
+
const flags = chunk.flags ? chunk.flags : 0;
|
|
138
|
+
const value = (0, HexToBuffer_1.HexToBuffer)(chunk.value ? chunk.value : '');
|
|
139
|
+
//Honor an explicit Chunk Length (a crafted chunk may lie / a decoded one carries
|
|
140
|
+
//its on-wire value); else derive it from the 4-byte header + value. For a decoded
|
|
141
|
+
//chunk these agree exactly, so the walk advances identically to decode.
|
|
142
|
+
const chunkLength = (chunk.length !== undefined && chunk.length !== null)
|
|
143
|
+
? chunk.length
|
|
144
|
+
: 4 + value.length;
|
|
145
|
+
this.writeBytes(offset, (0, NumberToBuffer_1.UInt8ToBuffer)(type));
|
|
146
|
+
this.writeBytes(offset + 1, (0, NumberToBuffer_1.UInt8ToBuffer)(flags));
|
|
147
|
+
this.writeBytes(offset + 2, (0, NumberToBuffer_1.UInt16ToBuffer)(chunkLength));
|
|
148
|
+
if (value.length)
|
|
149
|
+
this.writeBytes(offset + 4, value);
|
|
150
|
+
//Padding kept verbatim so a non-zero/truncated pad round-trips; when absent
|
|
151
|
+
//(crafting) it is derived as zero bytes to the next 4-byte boundary.
|
|
152
|
+
const padding = (chunk.padding !== undefined && chunk.padding !== null)
|
|
153
|
+
? (0, HexToBuffer_1.HexToBuffer)(chunk.padding)
|
|
154
|
+
: Buffer.alloc((4 - (chunkLength % 4)) % 4, 0);
|
|
155
|
+
if (padding.length)
|
|
156
|
+
this.writeBytes(offset + chunkLength, padding);
|
|
157
|
+
offset += chunkLength + padding.length;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
match() {
|
|
165
|
+
//SCTP sits directly above IPv4 (protocol field) or IPv6 (next-header field) with protocol 132,
|
|
166
|
+
//and needs at least its 12-byte common header within the IP payload.
|
|
167
|
+
if (!this.prevCodecModule)
|
|
168
|
+
return false;
|
|
169
|
+
if (this.prevCodecModule.instance.protocol.getValue() !== 0x84 && this.prevCodecModule.instance.nxt.getValue() !== 0x84)
|
|
170
|
+
return false;
|
|
171
|
+
return this.#available() >= 12;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
exports.SCTP = SCTP;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* sFlow v5 — sampled flow monitoring export (sflow.org v5 spec; historically RFC 3176 for v4). Rides
|
|
6
|
+
* UDP, conventionally destination port 6343. All fields are big-endian.
|
|
7
|
+
*
|
|
8
|
+
* The datagram header is: version (=5), agentAddressType (1 = IPv4, 2 = IPv6), the agent address
|
|
9
|
+
* (4 bytes for IPv4, 16 bytes for IPv6 — the ONLY variable-length part of the fixed header, and it
|
|
10
|
+
* shifts every downstream offset), subAgentId, sequenceNumber, sysUptime, and numSamples. Then
|
|
11
|
+
* `numSamples` sample records follow, each a 4-byte sampleType (enterprise << 12 | format), a 4-byte
|
|
12
|
+
* sampleLength, and sampleLength opaque bytes carried verbatim as hex (structuring the per-format
|
|
13
|
+
* flow/counter records is a later slice).
|
|
14
|
+
*
|
|
15
|
+
* The sample walk is bounded by BOTH `numSamples` and the bytes actually captured, so a lying
|
|
16
|
+
* numSamples in a truncated frame can never over-read; any trailing bytes fall to the raw layer.
|
|
17
|
+
* numSamples is honored when supplied (so a malformed datagram round-trips byte-for-byte) and derived
|
|
18
|
+
* from samples.length only when absent (crafting). This is a leaf header — nothing demuxes off sFlow.
|
|
19
|
+
*/
|
|
20
|
+
export declare class SFlow 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
|
+
}
|