@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,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SFlow = void 0;
|
|
4
|
+
const BaseHeader_1 = require("../abstracts/BaseHeader");
|
|
5
|
+
const BufferToNumber_1 = require("../helper/BufferToNumber");
|
|
6
|
+
const NumberToBuffer_1 = require("../helper/NumberToBuffer");
|
|
7
|
+
const BufferToIP_1 = require("../helper/BufferToIP");
|
|
8
|
+
const IPToBuffer_1 = require("../helper/IPToBuffer");
|
|
9
|
+
const BufferToHex_1 = require("../helper/BufferToHex");
|
|
10
|
+
const HexToBuffer_1 = require("../helper/HexToBuffer");
|
|
11
|
+
const StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
|
|
12
|
+
//Fixed geometry of an sFlow v5 datagram. The head up to (and including) agentAddressType is 8 bytes;
|
|
13
|
+
//the agent address is 4 bytes (IPv4) or 16 bytes (IPv6); then four 4-byte fields (subAgentId,
|
|
14
|
+
//sequenceNumber, sysUptime, numSamples) precede the sample list. Each sample carries an 8-byte tag
|
|
15
|
+
//(sampleType + sampleLength) followed by sampleLength opaque bytes.
|
|
16
|
+
const AGENT_ADDRESS_OFFSET = 8;
|
|
17
|
+
const IPV4_ADDRESS_LENGTH = 4;
|
|
18
|
+
const IPV6_ADDRESS_LENGTH = 16;
|
|
19
|
+
const AGENT_ADDRESS_TYPE_IPV6 = 2;
|
|
20
|
+
const TRAILER_FIELDS_LENGTH = 16;
|
|
21
|
+
const SAMPLE_TAG_LENGTH = 8;
|
|
22
|
+
/**
|
|
23
|
+
* sFlow v5 — sampled flow monitoring export (sflow.org v5 spec; historically RFC 3176 for v4). Rides
|
|
24
|
+
* UDP, conventionally destination port 6343. All fields are big-endian.
|
|
25
|
+
*
|
|
26
|
+
* The datagram header is: version (=5), agentAddressType (1 = IPv4, 2 = IPv6), the agent address
|
|
27
|
+
* (4 bytes for IPv4, 16 bytes for IPv6 — the ONLY variable-length part of the fixed header, and it
|
|
28
|
+
* shifts every downstream offset), subAgentId, sequenceNumber, sysUptime, and numSamples. Then
|
|
29
|
+
* `numSamples` sample records follow, each a 4-byte sampleType (enterprise << 12 | format), a 4-byte
|
|
30
|
+
* sampleLength, and sampleLength opaque bytes carried verbatim as hex (structuring the per-format
|
|
31
|
+
* flow/counter records is a later slice).
|
|
32
|
+
*
|
|
33
|
+
* The sample walk is bounded by BOTH `numSamples` and the bytes actually captured, so a lying
|
|
34
|
+
* numSamples in a truncated frame can never over-read; any trailing bytes fall to the raw layer.
|
|
35
|
+
* numSamples is honored when supplied (so a malformed datagram round-trips byte-for-byte) and derived
|
|
36
|
+
* from samples.length only when absent (crafting). This is a leaf header — nothing demuxes off sFlow.
|
|
37
|
+
*/
|
|
38
|
+
class SFlow extends BaseHeader_1.BaseHeader {
|
|
39
|
+
constructor() {
|
|
40
|
+
super(...arguments);
|
|
41
|
+
this.id = 'sflow';
|
|
42
|
+
this.name = 'sFlow v5';
|
|
43
|
+
this.nickname = 'sFlow';
|
|
44
|
+
//Port-defined (udp:6343). sFlow does carry a content signature — the first four bytes are the
|
|
45
|
+
//version (=5) — but that alone is weak, so it stays a plain bucket entry (no heuristicFallback):
|
|
46
|
+
//sFlow v5 only when it rides its well-known UDP port.
|
|
47
|
+
this.matchKeys = ['udpport:6343'];
|
|
48
|
+
//Leaf header: the sample records are terminal opaque data, nothing demuxes off sFlow.
|
|
49
|
+
this.demuxProducers = [];
|
|
50
|
+
}
|
|
51
|
+
static #schemaCache;
|
|
52
|
+
get SCHEMA() {
|
|
53
|
+
return (SFlow.#schemaCache ??= SFlow.#buildSchema());
|
|
54
|
+
}
|
|
55
|
+
/** Length in bytes of the agent address, driven by the decoded agentAddressType (IPv6 → 16, else 4). */
|
|
56
|
+
#agentAddressLength() {
|
|
57
|
+
return this.instance.agentAddressType.getValue(1) === AGENT_ADDRESS_TYPE_IPV6 ? IPV6_ADDRESS_LENGTH : IPV4_ADDRESS_LENGTH;
|
|
58
|
+
}
|
|
59
|
+
/** Offset of subAgentId — the first field after the variable-length agent address. */
|
|
60
|
+
#subAgentIdOffset() {
|
|
61
|
+
return AGENT_ADDRESS_OFFSET + this.#agentAddressLength();
|
|
62
|
+
}
|
|
63
|
+
/** Offset of the first sample record: the whole fixed header (address-type dependent). */
|
|
64
|
+
#headerLength() {
|
|
65
|
+
return this.#subAgentIdOffset() + TRAILER_FIELDS_LENGTH;
|
|
66
|
+
}
|
|
67
|
+
/** Bytes available for this sFlow datagram: the frame end, clamped by the UDP payload length. */
|
|
68
|
+
#available() {
|
|
69
|
+
let available = this.packet.length - this.startPos;
|
|
70
|
+
if (this.prevCodecModule && this.prevCodecModule.id === 'udp') {
|
|
71
|
+
const udpLength = this.prevCodecModule.instance.length.getValue(0);
|
|
72
|
+
if (udpLength >= 8 && udpLength - 8 < available)
|
|
73
|
+
available = udpLength - 8;
|
|
74
|
+
}
|
|
75
|
+
return available < 0 ? 0 : available;
|
|
76
|
+
}
|
|
77
|
+
/** A big-endian uint32 field at a dynamic (address-type driven) offset produced by `offset`. */
|
|
78
|
+
static #uint32At(name, offset, label) {
|
|
79
|
+
return {
|
|
80
|
+
type: 'integer',
|
|
81
|
+
label: label,
|
|
82
|
+
minimum: 0,
|
|
83
|
+
maximum: 4294967295,
|
|
84
|
+
decode: function () {
|
|
85
|
+
this.instance[name].setValue((0, BufferToNumber_1.BufferToUInt32)(this.readBytes(offset.call(this), 4)));
|
|
86
|
+
},
|
|
87
|
+
encode: function () {
|
|
88
|
+
const node = this.instance[name];
|
|
89
|
+
let value = node.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
|
|
90
|
+
if (value > 4294967295) {
|
|
91
|
+
this.recordError(node.getPath(), 'Maximum value is 4294967295');
|
|
92
|
+
value = 4294967295;
|
|
93
|
+
}
|
|
94
|
+
if (value < 0) {
|
|
95
|
+
this.recordError(node.getPath(), 'Minimum value is 0');
|
|
96
|
+
value = 0;
|
|
97
|
+
}
|
|
98
|
+
node.setValue(value);
|
|
99
|
+
this.writeBytes(offset.call(this), (0, NumberToBuffer_1.UInt32ToBuffer)(value));
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
static #buildSchema() {
|
|
104
|
+
return {
|
|
105
|
+
type: 'object',
|
|
106
|
+
summary: 'sFlow ${numSamples} samples',
|
|
107
|
+
properties: {
|
|
108
|
+
version: SFlow.fieldUInt('version', 0, 4, 'Version'),
|
|
109
|
+
agentAddressType: SFlow.fieldUInt('agentAddressType', 4, 4, 'Agent Address Type'),
|
|
110
|
+
//The only variable-length field of the fixed header: 4 bytes as a dotted quad for IPv4
|
|
111
|
+
//(type 1), 16 bytes kept verbatim as hex for IPv6 (type 2). Its length shifts every
|
|
112
|
+
//downstream offset, so all trailing fields compute their offset from #subAgentIdOffset().
|
|
113
|
+
agentAddress: {
|
|
114
|
+
type: 'string',
|
|
115
|
+
label: 'Agent Address',
|
|
116
|
+
decode: function () {
|
|
117
|
+
const length = this.instance.agentAddressType.getValue(1) === AGENT_ADDRESS_TYPE_IPV6 ? IPV6_ADDRESS_LENGTH : IPV4_ADDRESS_LENGTH;
|
|
118
|
+
const buffer = this.readBytes(AGENT_ADDRESS_OFFSET, length);
|
|
119
|
+
this.instance.agentAddress.setValue(length === IPV6_ADDRESS_LENGTH ? (0, BufferToHex_1.BufferToHex)(buffer) : (0, BufferToIP_1.BufferToIPv4)(buffer));
|
|
120
|
+
},
|
|
121
|
+
encode: function () {
|
|
122
|
+
const node = this.instance.agentAddress;
|
|
123
|
+
if (this.instance.agentAddressType.getValue(1) === AGENT_ADDRESS_TYPE_IPV6) {
|
|
124
|
+
const value = node.getValue('00'.repeat(IPV6_ADDRESS_LENGTH), (nodePath) => this.recordError(nodePath, 'Not Found'));
|
|
125
|
+
node.setValue(value);
|
|
126
|
+
this.writeBytes(AGENT_ADDRESS_OFFSET, (0, HexToBuffer_1.HexToBuffer)(value));
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
const value = node.getValue('0.0.0.0', (nodePath) => this.recordError(nodePath, 'Not Found'));
|
|
130
|
+
node.setValue(value);
|
|
131
|
+
this.writeBytes(AGENT_ADDRESS_OFFSET, (0, IPToBuffer_1.IPv4ToBuffer)(value));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
subAgentId: SFlow.#uint32At('subAgentId', function () {
|
|
136
|
+
return this.#subAgentIdOffset();
|
|
137
|
+
}, 'Sub Agent ID'),
|
|
138
|
+
sequenceNumber: SFlow.#uint32At('sequenceNumber', function () {
|
|
139
|
+
return this.#subAgentIdOffset() + 4;
|
|
140
|
+
}, 'Sequence Number'),
|
|
141
|
+
sysUptime: SFlow.#uint32At('sysUptime', function () {
|
|
142
|
+
return this.#subAgentIdOffset() + 8;
|
|
143
|
+
}, 'System Uptime'),
|
|
144
|
+
numSamples: {
|
|
145
|
+
type: 'integer',
|
|
146
|
+
label: 'Number of Samples',
|
|
147
|
+
minimum: 0,
|
|
148
|
+
maximum: 4294967295,
|
|
149
|
+
decode: function () {
|
|
150
|
+
this.instance.numSamples.setValue((0, BufferToNumber_1.BufferToUInt32)(this.readBytes(this.#subAgentIdOffset() + 12, 4)));
|
|
151
|
+
},
|
|
152
|
+
encode: function () {
|
|
153
|
+
//Honor an explicitly-set numSamples (even a lying one — so a malformed capture still
|
|
154
|
+
//round-trips byte-for-byte); derive from the sample array only when absent (crafting).
|
|
155
|
+
let numSamples = this.instance.numSamples.getValue();
|
|
156
|
+
if (numSamples === undefined || numSamples === null) {
|
|
157
|
+
const samples = this.instance.samples.getValue();
|
|
158
|
+
numSamples = Array.isArray(samples) ? samples.length : 0;
|
|
159
|
+
}
|
|
160
|
+
if (numSamples > 4294967295) {
|
|
161
|
+
this.recordError(this.instance.numSamples.getPath(), 'Maximum value is 4294967295');
|
|
162
|
+
numSamples = 4294967295;
|
|
163
|
+
}
|
|
164
|
+
if (numSamples < 0) {
|
|
165
|
+
this.recordError(this.instance.numSamples.getPath(), 'Minimum value is 0');
|
|
166
|
+
numSamples = 0;
|
|
167
|
+
}
|
|
168
|
+
this.instance.numSamples.setValue(numSamples);
|
|
169
|
+
this.writeBytes(this.#subAgentIdOffset() + 12, (0, NumberToBuffer_1.UInt32ToBuffer)(numSamples));
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
samples: {
|
|
173
|
+
type: 'array',
|
|
174
|
+
label: 'Samples',
|
|
175
|
+
items: {
|
|
176
|
+
type: 'object',
|
|
177
|
+
label: 'Sample',
|
|
178
|
+
properties: {
|
|
179
|
+
sampleType: { type: 'integer', label: 'Sample Type', minimum: 0, maximum: 4294967295 },
|
|
180
|
+
sampleLength: { type: 'integer', label: 'Sample Length', minimum: 0, maximum: 4294967295 },
|
|
181
|
+
sampleData: { type: 'string', label: 'Sample Data', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX }
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
decode: function () {
|
|
185
|
+
//Bound the walk by BOTH the declared numSamples and the captured bytes: a lying
|
|
186
|
+
//numSamples in a truncated frame must never read past the buffer. Each record is an
|
|
187
|
+
//8-byte tag (type + length) followed by `sampleLength` opaque bytes.
|
|
188
|
+
const numSamples = this.instance.numSamples.getValue(0);
|
|
189
|
+
const end = this.#available();
|
|
190
|
+
const samples = [];
|
|
191
|
+
let offset = this.#headerLength();
|
|
192
|
+
for (let i = 0; i < numSamples; i++) {
|
|
193
|
+
if (offset + SAMPLE_TAG_LENGTH > end)
|
|
194
|
+
break;
|
|
195
|
+
const sampleType = (0, BufferToNumber_1.BufferToUInt32)(this.readBytes(offset, 4, true));
|
|
196
|
+
const sampleLength = (0, BufferToNumber_1.BufferToUInt32)(this.readBytes(offset + 4, 4, true));
|
|
197
|
+
if (offset + SAMPLE_TAG_LENGTH + sampleLength > end)
|
|
198
|
+
break;
|
|
199
|
+
this.readBytes(offset, SAMPLE_TAG_LENGTH + sampleLength);
|
|
200
|
+
const sampleData = sampleLength > 0 ? (0, BufferToHex_1.BufferToHex)(this.packet.subarray(this.getPacketOffset(offset + SAMPLE_TAG_LENGTH), this.getPacketOffset(offset + SAMPLE_TAG_LENGTH + sampleLength))) : '';
|
|
201
|
+
samples.push({ sampleType: sampleType, sampleLength: sampleLength, sampleData: sampleData });
|
|
202
|
+
offset += SAMPLE_TAG_LENGTH + sampleLength;
|
|
203
|
+
}
|
|
204
|
+
this.instance.samples.setValue(samples);
|
|
205
|
+
},
|
|
206
|
+
encode: function () {
|
|
207
|
+
const samples = this.instance.samples.getValue();
|
|
208
|
+
if (!Array.isArray(samples))
|
|
209
|
+
return;
|
|
210
|
+
let offset = this.#headerLength();
|
|
211
|
+
for (const sample of samples) {
|
|
212
|
+
const body = (0, HexToBuffer_1.HexToBuffer)(sample.sampleData ? sample.sampleData : '');
|
|
213
|
+
//Honor an explicit sampleLength (byte-perfect for decoded frames), else derive
|
|
214
|
+
//it from the opaque body.
|
|
215
|
+
const sampleLength = (sample.sampleLength !== undefined && sample.sampleLength !== null)
|
|
216
|
+
? sample.sampleLength
|
|
217
|
+
: body.length;
|
|
218
|
+
this.writeBytes(offset, (0, NumberToBuffer_1.UInt32ToBuffer)(sample.sampleType ? sample.sampleType : 0));
|
|
219
|
+
this.writeBytes(offset + 4, (0, NumberToBuffer_1.UInt32ToBuffer)(sampleLength));
|
|
220
|
+
offset += SAMPLE_TAG_LENGTH;
|
|
221
|
+
if (body.length) {
|
|
222
|
+
this.writeBytes(offset, body);
|
|
223
|
+
offset += body.length;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
match() {
|
|
232
|
+
if (!this.prevCodecModule || this.prevCodecModule.id !== 'udp')
|
|
233
|
+
return false;
|
|
234
|
+
//Require the smallest possible datagram (IPv4-agent header = 28 bytes) and the version
|
|
235
|
+
//signature (=5). Anything else on port 6343 falls through to raw.
|
|
236
|
+
if (this.#available() < 28)
|
|
237
|
+
return false;
|
|
238
|
+
const version = (0, BufferToNumber_1.BufferToUInt32)(this.packet.subarray(this.startPos, this.startPos + 4));
|
|
239
|
+
return version === 5;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
exports.SFlow = SFlow;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* SIP — the Session Initiation Protocol (RFC 3261), the signalling protocol for VoIP/IMS carried over
|
|
6
|
+
* UDP or TCP port 5060. A SIP message is US-ASCII text: a start-line, then header lines, a CRLF, and an
|
|
7
|
+
* optional body. The start-line is either a Request-Line (`METHOD SP Request-URI SP SIP-Version CRLF`)
|
|
8
|
+
* or a Status-Line (`SIP-Version SP Status-Code SP Reason-Phrase CRLF`).
|
|
9
|
+
*
|
|
10
|
+
* Like Syslog, the message body is text whose full internal structure (dozens of header fields, an
|
|
11
|
+
* arbitrary body of any content-type) is far richer than a form needs — and whitespace/header ordering
|
|
12
|
+
* is significant to some peers. So the ENTIRE raw message is kept verbatim as the authoritative
|
|
13
|
+
* `message` field (hex) and re-emitted untouched; only the start-line is parsed on decode into
|
|
14
|
+
* display-only metadata (method/uri/version or status-code/reason). Encode never reconstructs the
|
|
15
|
+
* message from the parsed fields — it writes `message` back byte-for-byte — so any conformant (or even
|
|
16
|
+
* malformed) SIP message round-trips exactly.
|
|
17
|
+
*/
|
|
18
|
+
export declare class SIP extends BaseHeader {
|
|
19
|
+
#private;
|
|
20
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly name: string;
|
|
23
|
+
readonly nickname: string;
|
|
24
|
+
readonly matchKeys: string[];
|
|
25
|
+
match(): boolean;
|
|
26
|
+
readonly demuxProducers: DemuxProducer[];
|
|
27
|
+
}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var _a;
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.SIP = void 0;
|
|
5
|
+
const BaseHeader_1 = require("../abstracts/BaseHeader");
|
|
6
|
+
const BufferToHex_1 = require("../helper/BufferToHex");
|
|
7
|
+
const HexToBuffer_1 = require("../helper/HexToBuffer");
|
|
8
|
+
const StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
|
|
9
|
+
/** SIP request methods (RFC 3261 + common extensions) used only to recognize a request start-line. */
|
|
10
|
+
const SIP_METHODS = ['INVITE', 'ACK', 'BYE', 'CANCEL', 'OPTIONS', 'REGISTER', 'PRACK', 'SUBSCRIBE', 'NOTIFY', 'PUBLISH', 'INFO', 'REFER', 'MESSAGE', 'UPDATE'];
|
|
11
|
+
/**
|
|
12
|
+
* SIP — the Session Initiation Protocol (RFC 3261), the signalling protocol for VoIP/IMS carried over
|
|
13
|
+
* UDP or TCP port 5060. A SIP message is US-ASCII text: a start-line, then header lines, a CRLF, and an
|
|
14
|
+
* optional body. The start-line is either a Request-Line (`METHOD SP Request-URI SP SIP-Version CRLF`)
|
|
15
|
+
* or a Status-Line (`SIP-Version SP Status-Code SP Reason-Phrase CRLF`).
|
|
16
|
+
*
|
|
17
|
+
* Like Syslog, the message body is text whose full internal structure (dozens of header fields, an
|
|
18
|
+
* arbitrary body of any content-type) is far richer than a form needs — and whitespace/header ordering
|
|
19
|
+
* is significant to some peers. So the ENTIRE raw message is kept verbatim as the authoritative
|
|
20
|
+
* `message` field (hex) and re-emitted untouched; only the start-line is parsed on decode into
|
|
21
|
+
* display-only metadata (method/uri/version or status-code/reason). Encode never reconstructs the
|
|
22
|
+
* message from the parsed fields — it writes `message` back byte-for-byte — so any conformant (or even
|
|
23
|
+
* malformed) SIP message round-trips exactly.
|
|
24
|
+
*/
|
|
25
|
+
class SIP extends BaseHeader_1.BaseHeader {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
this.id = 'sip';
|
|
29
|
+
this.name = 'Session Initiation Protocol';
|
|
30
|
+
this.nickname = 'SIP';
|
|
31
|
+
this.matchKeys = ['udpport:5060', 'tcpport:5060'];
|
|
32
|
+
//A leaf header — the SIP body (SDP, etc.) and the dialog it belongs to are a higher-layer concern.
|
|
33
|
+
this.demuxProducers = [];
|
|
34
|
+
}
|
|
35
|
+
static #schemaCache;
|
|
36
|
+
get SCHEMA() {
|
|
37
|
+
return (_a.#schemaCache ??= _a.#buildSchema());
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Bytes of this header: for UDP, bounded by the datagram length (so a retained FCS/padding is not
|
|
41
|
+
* absorbed); for TCP there is no per-message length, so take the rest of the segment.
|
|
42
|
+
*/
|
|
43
|
+
#payloadLength() {
|
|
44
|
+
let available = this.packet.length - this.startPos;
|
|
45
|
+
if (this.prevCodecModule && this.prevCodecModule.id === 'udp') {
|
|
46
|
+
const udpLength = this.prevCodecModule.instance.length.getValue(0);
|
|
47
|
+
if (udpLength >= 8 && udpLength - 8 < available)
|
|
48
|
+
available = udpLength - 8;
|
|
49
|
+
}
|
|
50
|
+
return available < 0 ? 0 : available;
|
|
51
|
+
}
|
|
52
|
+
/** The first line of the message (up to the first CRLF, or the whole payload if none). */
|
|
53
|
+
static #firstLine(text) {
|
|
54
|
+
const idx = text.indexOf('\r\n');
|
|
55
|
+
return idx >= 0 ? text.slice(0, idx) : text;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Parse the start-line into the display-only metadata fields. A Status-Line begins with the
|
|
59
|
+
* SIP-Version ("SIP/2.0"); anything else is treated as a Request-Line. Populated on decode only —
|
|
60
|
+
* these fields have no encode, so they never affect the re-emitted bytes.
|
|
61
|
+
*/
|
|
62
|
+
#parseStartLine(text) {
|
|
63
|
+
const line = _a.#firstLine(text);
|
|
64
|
+
if (line.startsWith('SIP/')) {
|
|
65
|
+
//Status-Line: SIP-Version SP Status-Code SP Reason-Phrase
|
|
66
|
+
const match = line.match(/^(\S+)\s+(\d{3})\s*(.*)$/);
|
|
67
|
+
this.instance.isRequest.setValue(false);
|
|
68
|
+
this.instance.method.setValue('');
|
|
69
|
+
this.instance.requestUri.setValue('');
|
|
70
|
+
this.instance.version.setValue(match ? match[1] : (line.split(' ')[0] || ''));
|
|
71
|
+
this.instance.statusCode.setValue(match ? Number(match[2]) : 0);
|
|
72
|
+
this.instance.reasonPhrase.setValue(match ? match[3] : '');
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
//Request-Line: METHOD SP Request-URI SP SIP-Version
|
|
76
|
+
const parts = line.split(' ');
|
|
77
|
+
this.instance.isRequest.setValue(true);
|
|
78
|
+
this.instance.method.setValue(parts[0] ? parts[0] : '');
|
|
79
|
+
this.instance.requestUri.setValue(parts.length > 1 ? parts[1] : '');
|
|
80
|
+
//The SIP-Version is the last whitespace-delimited token; the Request-URI itself has no spaces.
|
|
81
|
+
this.instance.version.setValue(parts.length > 2 ? parts[parts.length - 1] : '');
|
|
82
|
+
this.instance.statusCode.setValue(0);
|
|
83
|
+
this.instance.reasonPhrase.setValue('');
|
|
84
|
+
}
|
|
85
|
+
static #buildSchema() {
|
|
86
|
+
return {
|
|
87
|
+
type: 'object',
|
|
88
|
+
summary: 'SIP ${method}${statusCode}',
|
|
89
|
+
properties: {
|
|
90
|
+
//The whole raw message is the single source of truth: decoded verbatim to hex and
|
|
91
|
+
//re-emitted untouched (byte-perfect for any SIP message). The start-line is parsed into
|
|
92
|
+
//the display-only metadata below, which carry no codec of their own.
|
|
93
|
+
message: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
label: 'Message',
|
|
96
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
97
|
+
decode: function () {
|
|
98
|
+
const available = this.#payloadLength();
|
|
99
|
+
if (available <= 0) {
|
|
100
|
+
this.instance.message.setValue('');
|
|
101
|
+
this.#parseStartLine('');
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const raw = this.readBytes(0, available);
|
|
105
|
+
this.instance.message.setValue((0, BufferToHex_1.BufferToHex)(raw));
|
|
106
|
+
this.#parseStartLine(raw.toString('latin1'));
|
|
107
|
+
},
|
|
108
|
+
encode: function () {
|
|
109
|
+
//Re-emit the authoritative message verbatim — never reconstruct from metadata.
|
|
110
|
+
this.writeBytes(0, (0, HexToBuffer_1.HexToBuffer)(this.instance.message.getValue('')));
|
|
111
|
+
}
|
|
112
|
+
},
|
|
113
|
+
//Display-only metadata parsed from the start-line on decode (no encode — populated by the
|
|
114
|
+
//message field above, never read back). isRequest distinguishes a Request-Line from a
|
|
115
|
+
//Status-Line; method/requestUri are for requests, statusCode/reasonPhrase for responses.
|
|
116
|
+
isRequest: { type: 'boolean', label: 'Is Request' },
|
|
117
|
+
method: { type: 'string', label: 'Method' },
|
|
118
|
+
requestUri: { type: 'string', label: 'Request URI' },
|
|
119
|
+
version: { type: 'string', label: 'Version' },
|
|
120
|
+
statusCode: { type: 'integer', label: 'Status Code', minimum: 0, maximum: 999 },
|
|
121
|
+
reasonPhrase: { type: 'string', label: 'Reason Phrase' }
|
|
122
|
+
}
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
match() {
|
|
126
|
+
//SIP rides on UDP/TCP port 5060 as US-ASCII text. Recognize it by the start-line signature: a
|
|
127
|
+
//known request method followed by a space, or the "SIP/2.0" response version — so non-SIP
|
|
128
|
+
//traffic on port 5060 falls through to raw rather than claiming an un-decodable text layer.
|
|
129
|
+
if (!this.prevCodecModule)
|
|
130
|
+
return false;
|
|
131
|
+
if (this.prevCodecModule.id !== 'udp' && this.prevCodecModule.id !== 'tcp')
|
|
132
|
+
return false;
|
|
133
|
+
if (this.#payloadLength() <= 0)
|
|
134
|
+
return false;
|
|
135
|
+
const lead = this.readBytes(0, 16, true).toString('latin1');
|
|
136
|
+
if (lead.startsWith('SIP/2.0'))
|
|
137
|
+
return true;
|
|
138
|
+
for (const method of SIP_METHODS) {
|
|
139
|
+
if (lead.startsWith(method + ' '))
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
return false;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
exports.SIP = SIP;
|
|
146
|
+
_a = SIP;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* SLMP — SeamLess Message Protocol (Mitsubishi Electric MELSEC / iQ-R, "SLMP"), the open industrial
|
|
6
|
+
* protocol that carries MELSEC device read/write and control requests, commonly on TCP & UDP port 5007.
|
|
7
|
+
* This codec models the ubiquitous 3E-frame BINARY encoding. Every 3E request begins with the subheader
|
|
8
|
+
* 0x5000 (wire bytes `50 00`) and every response with 0xD000 (`D0 00`), followed by a small routing
|
|
9
|
+
* header — Network number, Station (PC) number, request-destination Module I/O number, Multidrop station
|
|
10
|
+
* number — then a Request Data Length that counts every byte AFTER it, and finally the command payload
|
|
11
|
+
* (for a request: Monitor Timer + Command + Subcommand + device specification; for a response: End Code +
|
|
12
|
+
* response data).
|
|
13
|
+
*
|
|
14
|
+
* ⚠️ Except for the 2-byte subheader marker (kept in wire order as `50 00` / `D0 00`, i.e. big-endian
|
|
15
|
+
* 0x5000 / 0xD000), every multi-byte field in the 3E binary frame is LITTLE-ENDIAN. There is no
|
|
16
|
+
* little-endian helper in this codebase, so the uint16 fields are read/written byte-by-byte in their
|
|
17
|
+
* closures.
|
|
18
|
+
*
|
|
19
|
+
* Byte-perfect strategy (minimal slice, per the SLMP layout being command-dependent): structure the
|
|
20
|
+
* subheader + routing header + Request Data Length, and keep the command-specific remainder (Monitor
|
|
21
|
+
* Timer / Command / Subcommand / device data on a request; End Code / data on a response) verbatim as
|
|
22
|
+
* `data` hex. The remainder is bounded by the Request Data Length (data ends at offset 9 + length) and
|
|
23
|
+
* the captured bytes, so a trailing / pipelined message is left to the codec's recursion / RawData. The
|
|
24
|
+
* Request Data Length is auto-computed from the data on encode when not supplied, else honored verbatim
|
|
25
|
+
* (a crafted frame may carry any length). A well-formed message round-trips byte-for-byte.
|
|
26
|
+
*/
|
|
27
|
+
export declare class SLMP extends BaseHeader {
|
|
28
|
+
#private;
|
|
29
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
30
|
+
readonly id: string;
|
|
31
|
+
readonly name: string;
|
|
32
|
+
readonly nickname: string;
|
|
33
|
+
readonly matchKeys: string[];
|
|
34
|
+
match(): boolean;
|
|
35
|
+
readonly demuxProducers: DemuxProducer[];
|
|
36
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SLMP = 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 StringContentEncodingEnum_1 = require("../lib/StringContentEncodingEnum");
|
|
8
|
+
/**
|
|
9
|
+
* SLMP — SeamLess Message Protocol (Mitsubishi Electric MELSEC / iQ-R, "SLMP"), the open industrial
|
|
10
|
+
* protocol that carries MELSEC device read/write and control requests, commonly on TCP & UDP port 5007.
|
|
11
|
+
* This codec models the ubiquitous 3E-frame BINARY encoding. Every 3E request begins with the subheader
|
|
12
|
+
* 0x5000 (wire bytes `50 00`) and every response with 0xD000 (`D0 00`), followed by a small routing
|
|
13
|
+
* header — Network number, Station (PC) number, request-destination Module I/O number, Multidrop station
|
|
14
|
+
* number — then a Request Data Length that counts every byte AFTER it, and finally the command payload
|
|
15
|
+
* (for a request: Monitor Timer + Command + Subcommand + device specification; for a response: End Code +
|
|
16
|
+
* response data).
|
|
17
|
+
*
|
|
18
|
+
* ⚠️ Except for the 2-byte subheader marker (kept in wire order as `50 00` / `D0 00`, i.e. big-endian
|
|
19
|
+
* 0x5000 / 0xD000), every multi-byte field in the 3E binary frame is LITTLE-ENDIAN. There is no
|
|
20
|
+
* little-endian helper in this codebase, so the uint16 fields are read/written byte-by-byte in their
|
|
21
|
+
* closures.
|
|
22
|
+
*
|
|
23
|
+
* Byte-perfect strategy (minimal slice, per the SLMP layout being command-dependent): structure the
|
|
24
|
+
* subheader + routing header + Request Data Length, and keep the command-specific remainder (Monitor
|
|
25
|
+
* Timer / Command / Subcommand / device data on a request; End Code / data on a response) verbatim as
|
|
26
|
+
* `data` hex. The remainder is bounded by the Request Data Length (data ends at offset 9 + length) and
|
|
27
|
+
* the captured bytes, so a trailing / pipelined message is left to the codec's recursion / RawData. The
|
|
28
|
+
* Request Data Length is auto-computed from the data on encode when not supplied, else honored verbatim
|
|
29
|
+
* (a crafted frame may carry any length). A well-formed message round-trips byte-for-byte.
|
|
30
|
+
*/
|
|
31
|
+
class SLMP extends BaseHeader_1.BaseHeader {
|
|
32
|
+
constructor() {
|
|
33
|
+
super(...arguments);
|
|
34
|
+
this.id = 'slmp';
|
|
35
|
+
this.name = 'SeamLess Message Protocol';
|
|
36
|
+
this.nickname = 'SLMP';
|
|
37
|
+
//MELSEC SLMP rides TCP/UDP port 5007 (selected via the tcpport:5007 / udpport:5007 buckets). This
|
|
38
|
+
//stays a port-bucket protocol: matchKeys only, NO heuristicFallback — the subheader is only a 2-byte
|
|
39
|
+
//marker, too weak to claim SLMP off port 5007, so non-SLMP 5007 traffic falls through to raw.
|
|
40
|
+
this.matchKeys = ['tcpport:5007', 'udpport:5007'];
|
|
41
|
+
//A leaf header — the command-specific device payload requires per-command parsing.
|
|
42
|
+
this.demuxProducers = [];
|
|
43
|
+
}
|
|
44
|
+
static #schemaCache;
|
|
45
|
+
get SCHEMA() {
|
|
46
|
+
return (SLMP.#schemaCache ??= SLMP.#buildSchema());
|
|
47
|
+
}
|
|
48
|
+
/** A little-endian unsigned 16-bit field of 2 octets at `offset`. */
|
|
49
|
+
static #fieldUInt16LE(name, offset, label) {
|
|
50
|
+
return {
|
|
51
|
+
type: 'integer',
|
|
52
|
+
label: label,
|
|
53
|
+
minimum: 0,
|
|
54
|
+
maximum: 65535,
|
|
55
|
+
decode: function () {
|
|
56
|
+
const b = this.readBytes(offset, 2);
|
|
57
|
+
this.instance[name].setValue(b[0] | (b[1] << 8));
|
|
58
|
+
},
|
|
59
|
+
encode: function () {
|
|
60
|
+
const node = this.instance[name];
|
|
61
|
+
let value = node.getValue(0, (nodePath) => this.recordError(nodePath, 'Not Found'));
|
|
62
|
+
if (value > 65535) {
|
|
63
|
+
this.recordError(node.getPath(), 'Maximum value is 65535');
|
|
64
|
+
value = 65535;
|
|
65
|
+
}
|
|
66
|
+
if (value < 0) {
|
|
67
|
+
this.recordError(node.getPath(), 'Minimum value is 0');
|
|
68
|
+
value = 0;
|
|
69
|
+
}
|
|
70
|
+
node.setValue(value);
|
|
71
|
+
this.writeBytes(offset, Buffer.from([value & 0xff, (value >> 8) & 0xff]));
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
static #buildSchema() {
|
|
76
|
+
return {
|
|
77
|
+
type: 'object',
|
|
78
|
+
summary: 'SLMP subheader=${subheader} len=${requestDataLength}',
|
|
79
|
+
properties: {
|
|
80
|
+
//The 2-byte frame marker, kept in wire order (big-endian): 0x5000 (`50 00`) request,
|
|
81
|
+
//0xD000 (`D0 00`) response. Not little-endian — it is a fixed signature, not a value.
|
|
82
|
+
subheader: this.fieldUInt('subheader', 0, 2, 'Subheader'),
|
|
83
|
+
networkNo: this.fieldUInt('networkNo', 2, 1, 'Network Number'),
|
|
84
|
+
stationNo: this.fieldUInt('stationNo', 3, 1, 'Station Number'),
|
|
85
|
+
//Request-destination Module I/O number (little-endian, e.g. 0x03FF = own station).
|
|
86
|
+
moduleIO: this.#fieldUInt16LE('moduleIO', 4, 'Module I/O Number'),
|
|
87
|
+
multidropStation: this.fieldUInt('multidropStation', 6, 1, 'Multidrop Station Number'),
|
|
88
|
+
//Counts every byte that FOLLOWS this field (Monitor Timer + Command + Subcommand + device
|
|
89
|
+
//data on a request; End Code + data on a response). Honored when supplied (a crafted frame
|
|
90
|
+
//may lie); else derived from the encoded `data` length.
|
|
91
|
+
requestDataLength: {
|
|
92
|
+
type: 'integer',
|
|
93
|
+
label: 'Request Data Length',
|
|
94
|
+
minimum: 0,
|
|
95
|
+
maximum: 65535,
|
|
96
|
+
decode: function () {
|
|
97
|
+
const b = this.readBytes(7, 2);
|
|
98
|
+
this.instance.requestDataLength.setValue(b[0] | (b[1] << 8));
|
|
99
|
+
},
|
|
100
|
+
encode: function () {
|
|
101
|
+
const provided = this.instance.requestDataLength.getValue();
|
|
102
|
+
let value = (provided !== undefined && provided !== null)
|
|
103
|
+
? provided
|
|
104
|
+
: (0, HexToBuffer_1.HexToBuffer)(this.instance.data.getValue('')).length;
|
|
105
|
+
if (value > 65535) {
|
|
106
|
+
this.recordError(this.instance.requestDataLength.getPath(), 'Maximum value is 65535');
|
|
107
|
+
value = 65535;
|
|
108
|
+
}
|
|
109
|
+
if (value < 0) {
|
|
110
|
+
this.recordError(this.instance.requestDataLength.getPath(), 'Minimum value is 0');
|
|
111
|
+
value = 0;
|
|
112
|
+
}
|
|
113
|
+
this.instance.requestDataLength.setValue(value);
|
|
114
|
+
this.writeBytes(7, Buffer.from([value & 0xff, (value >> 8) & 0xff]));
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
//The command-specific remainder, kept verbatim. Bounded by Request Data Length (the frame
|
|
118
|
+
//ends at offset 9 + length) and the captured bytes, so trailing / pipelined data is left
|
|
119
|
+
//to the codec's recursion / RawData.
|
|
120
|
+
data: {
|
|
121
|
+
type: 'string',
|
|
122
|
+
label: 'Data',
|
|
123
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
124
|
+
decode: function () {
|
|
125
|
+
const available = this.packet.length - this.startPos;
|
|
126
|
+
const length = this.instance.requestDataLength.getValue(0);
|
|
127
|
+
let end = 9 + length;
|
|
128
|
+
if (end > available)
|
|
129
|
+
end = available;
|
|
130
|
+
this.instance.data.setValue(end > 9 ? (0, BufferToHex_1.BufferToHex)(this.readBytes(9, end - 9)) : '');
|
|
131
|
+
},
|
|
132
|
+
encode: function () {
|
|
133
|
+
const data = this.instance.data.getValue('');
|
|
134
|
+
if (data)
|
|
135
|
+
this.writeBytes(9, (0, HexToBuffer_1.HexToBuffer)(data));
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
match() {
|
|
142
|
+
//SLMP rides TCP/UDP port 5007. Require the full 9-byte 3E-frame header and a valid 3E-binary
|
|
143
|
+
//subheader (0x5000 request or 0xD000 response) so non-SLMP 5007 traffic falls through to raw.
|
|
144
|
+
if (!this.prevCodecModule)
|
|
145
|
+
return false;
|
|
146
|
+
if (this.prevCodecModule.id !== 'tcp' && this.prevCodecModule.id !== 'udp')
|
|
147
|
+
return false;
|
|
148
|
+
if (this.packet.length - this.startPos < 9)
|
|
149
|
+
return false;
|
|
150
|
+
const subheader = (0, BufferToHex_1.BufferToHex)(this.readBytes(0, 2, true));
|
|
151
|
+
return subheader === '5000' || subheader === 'd000';
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
exports.SLMP = SLMP;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* SLP — Service Location Protocol Version 2 (RFC 2608), UDP (and TCP) port 427. Every SLPv2 message
|
|
6
|
+
* begins with a common header: an 8-bit Version (2), an 8-bit Function-ID (1 SrvRqst, 2 SrvRply,
|
|
7
|
+
* 3 SrvReg, 4 SrvDeReg, 5 SrvAck, 6 AttrRqst, 7 AttrRply, 8 DAAdvert, 9 SrvTypeRqst, 10 SrvTypeRply,
|
|
8
|
+
* 11 SAAdvert), a 24-bit Length (the entire message octet count including this header), a 16-bit Flags
|
|
9
|
+
* field (bit 0 Overflow, bit 1 Fresh, bit 2 Request-multicast, the remaining 13 bits reserved), a 24-bit
|
|
10
|
+
* Next Extension Offset, a 16-bit XID, a 16-bit Language Tag Length and the Language Tag of that many
|
|
11
|
+
* octets — then the Function-ID-specific body.
|
|
12
|
+
*
|
|
13
|
+
* The body layout differs per Function-ID (SrvRqst's PRList/service-type/scope/predicate/SPL SPI,
|
|
14
|
+
* SrvRply's URL entries, SrvReg's URL + attributes, …) and several sub-structures carry authentication
|
|
15
|
+
* blocks and cross-message context, so this common-header codec keeps the body verbatim as `body` hex
|
|
16
|
+
* (byte-perfect) and does not sub-decode it. The Length is auto-computed on encode when not supplied,
|
|
17
|
+
* else honored verbatim (a crafted message may lie); the Language Tag Length is likewise honor-else-
|
|
18
|
+
* derive. The message is bounded by its Length (and the UDP datagram) so trailing / pipelined bytes are
|
|
19
|
+
* left to the codec's recursion / RawData. A well-formed message round-trips byte-for-byte.
|
|
20
|
+
*/
|
|
21
|
+
export declare class SLP 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
|
+
}
|