@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,135 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.KNXnetIP = 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
|
+
* KNXnet/IP (KNX over IP, ISO/IEC 14543-3, KNX Association 03/03/02), UDP port 3671 — the IP transport
|
|
12
|
+
* of the KNX building-automation bus (tunnelling KNX telegrams over IP and routing them between KNXnet/IP
|
|
13
|
+
* routers). Every KNXnet/IP frame begins with a fixed 6-byte header — Header Length (always 0x06 for the
|
|
14
|
+
* current spec), Protocol Version (0x10 = 1.0), a 2-byte Service Type Identifier and a 2-byte Total Length
|
|
15
|
+
* (the whole frame octet count INCLUDING this 6-byte header) — followed by the service-specific body.
|
|
16
|
+
*
|
|
17
|
+
* Common Service Type Identifiers: 0x0201 SEARCH_REQUEST, 0x0202 SEARCH_RESPONSE, 0x0205 CONNECT_REQUEST,
|
|
18
|
+
* 0x0420 TUNNELLING_REQUEST, 0x0530 ROUTING_INDICATION.
|
|
19
|
+
*
|
|
20
|
+
* The body layout differs per service type (HPAI discovery endpoints, connection headers, cEMI frames)
|
|
21
|
+
* and several sub-structures need connection/service context, so this single-frame codec keeps the body
|
|
22
|
+
* verbatim as `body` hex (byte-perfect) and does not sub-decode it. The Total Length is auto-computed from
|
|
23
|
+
* the body on encode when not supplied, else honored verbatim (a crafted frame may lie); the frame is
|
|
24
|
+
* bounded by Total Length (and the enclosing UDP payload) so trailing bytes are left to the codec's
|
|
25
|
+
* recursion / RawData. A well-formed frame round-trips byte-for-byte.
|
|
26
|
+
*/
|
|
27
|
+
class KNXnetIP extends BaseHeader_1.BaseHeader {
|
|
28
|
+
constructor() {
|
|
29
|
+
super(...arguments);
|
|
30
|
+
this.id = 'knxnetip';
|
|
31
|
+
this.name = 'KNXnet/IP';
|
|
32
|
+
this.nickname = 'KNXnet/IP';
|
|
33
|
+
this.matchKeys = ['udpport:3671'];
|
|
34
|
+
//A leaf header — the service-specific body requires per-service, connection-dependent parsing.
|
|
35
|
+
this.demuxProducers = [];
|
|
36
|
+
}
|
|
37
|
+
static #schemaCache;
|
|
38
|
+
get SCHEMA() {
|
|
39
|
+
return (KNXnetIP.#schemaCache ??= KNXnetIP.#buildSchema());
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* End offset (header-relative) of this KNXnet/IP frame: the Total Length, clamped to the enclosing
|
|
43
|
+
* UDP payload (udp.length − 8) when present and to the captured bytes. Bounding by the UDP payload as
|
|
44
|
+
* well as Total Length keeps a lying Total Length from swallowing trailing bytes and keeps a short
|
|
45
|
+
* capture in range.
|
|
46
|
+
*/
|
|
47
|
+
static #frameEnd(self) {
|
|
48
|
+
let end = self.instance.totalLength.getValue(0);
|
|
49
|
+
const available = self.packet.length - self.startPos;
|
|
50
|
+
const prev = self.prevCodecModule;
|
|
51
|
+
if (prev && prev.id === 'udp') {
|
|
52
|
+
const udpLength = prev.instance.length.getValue(0);
|
|
53
|
+
const udpPayload = udpLength - 8;
|
|
54
|
+
if (udpPayload >= 6 && udpPayload < end)
|
|
55
|
+
end = udpPayload;
|
|
56
|
+
}
|
|
57
|
+
if (end > available)
|
|
58
|
+
end = available;
|
|
59
|
+
return end < 0 ? 0 : end;
|
|
60
|
+
}
|
|
61
|
+
static #buildSchema() {
|
|
62
|
+
return {
|
|
63
|
+
type: 'object',
|
|
64
|
+
summary: 'KNXnet/IP service=${serviceType} len=${totalLength}',
|
|
65
|
+
properties: {
|
|
66
|
+
//Header Length — the size of this header in octets, 0x06 for the current KNXnet/IP spec.
|
|
67
|
+
//Kept as a plain clamped byte (honored verbatim) so a crafted frame still round-trips.
|
|
68
|
+
headerLength: this.fieldUInt('headerLength', 0, 1, 'Header Length'),
|
|
69
|
+
//Protocol Version — 0x10 (1.0) for the current spec. Kept verbatim.
|
|
70
|
+
protocolVersion: this.fieldUInt('protocolVersion', 1, 1, 'Protocol Version'),
|
|
71
|
+
//Service Type Identifier (e.g. 0x0201 SEARCH_REQUEST, 0x0420 TUNNELLING_REQUEST). Kept as a
|
|
72
|
+
//plain clamped uint16 (NOT an Ajv enum) so any non-standard / crafted service type decoded
|
|
73
|
+
//from the wire still re-encodes without being rejected — decode never fails, encode faithful.
|
|
74
|
+
serviceType: this.fieldUInt('serviceType', 2, 2, 'Service Type'),
|
|
75
|
+
totalLength: {
|
|
76
|
+
type: 'integer',
|
|
77
|
+
label: 'Total Length',
|
|
78
|
+
//minimum 0 (not 6): a crafted/corrupt frame may carry a Total Length below the 6-byte
|
|
79
|
+
//header, and that value must round-trip (honored verbatim) rather than be rejected by
|
|
80
|
+
//Ajv at the encode entry — decode never fails, encode is a faithful executor.
|
|
81
|
+
minimum: 0,
|
|
82
|
+
maximum: 65535,
|
|
83
|
+
decode: function () {
|
|
84
|
+
this.instance.totalLength.setValue((0, BufferToNumber_1.BufferToUInt16)(this.readBytes(4, 2)));
|
|
85
|
+
},
|
|
86
|
+
encode: function () {
|
|
87
|
+
//Total Length counts the whole frame = 6-byte header + body. Honored when supplied
|
|
88
|
+
//(a crafted frame may lie); else derived from the body.
|
|
89
|
+
const provided = this.instance.totalLength.getValue();
|
|
90
|
+
let value = (provided !== undefined && provided !== null)
|
|
91
|
+
? provided
|
|
92
|
+
: 6 + (0, HexToBuffer_1.HexToBuffer)(this.instance.body.getValue('')).length;
|
|
93
|
+
if (value > 65535) {
|
|
94
|
+
this.recordError(this.instance.totalLength.getPath(), 'Maximum value is 65535');
|
|
95
|
+
value = 65535;
|
|
96
|
+
}
|
|
97
|
+
this.instance.totalLength.setValue(value);
|
|
98
|
+
this.writeBytes(4, (0, NumberToBuffer_1.UInt16ToBuffer)(value));
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
//The service-specific body after the 6-byte header, kept verbatim. Bounded by the Total
|
|
102
|
+
//Length (frame ends at offset Total Length), the enclosing UDP payload and the captured
|
|
103
|
+
//bytes, so trailing / pipelined data is left to the codec's recursion / RawData.
|
|
104
|
+
body: {
|
|
105
|
+
type: 'string',
|
|
106
|
+
label: 'Body',
|
|
107
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
108
|
+
decode: function () {
|
|
109
|
+
const end = KNXnetIP.#frameEnd(this);
|
|
110
|
+
this.instance.body.setValue(end > 6 ? (0, BufferToHex_1.BufferToHex)(this.readBytes(6, end - 6)) : '');
|
|
111
|
+
},
|
|
112
|
+
encode: function () {
|
|
113
|
+
const body = this.instance.body.getValue('');
|
|
114
|
+
if (body)
|
|
115
|
+
this.writeBytes(6, (0, HexToBuffer_1.HexToBuffer)(body));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
match() {
|
|
122
|
+
//KNXnet/IP rides on UDP port 3671. The header carries no strong content magic, but the first two
|
|
123
|
+
//octets are effectively a fixed signature for the current spec: Header Length 0x06 and Protocol
|
|
124
|
+
//Version 0x10. Require the full 6-byte header plus that signature so non-KNX 3671 traffic falls
|
|
125
|
+
//through to raw. Selection stays port-bucketed (matchKeys), like the other length-bounded UDP
|
|
126
|
+
//payload codecs.
|
|
127
|
+
if (!this.prevCodecModule || this.prevCodecModule.id !== 'udp')
|
|
128
|
+
return false;
|
|
129
|
+
if (this.packet.length - this.startPos < 6)
|
|
130
|
+
return false;
|
|
131
|
+
const header = this.readBytes(0, 2, true);
|
|
132
|
+
return header[0] === 0x06 && header[1] === 0x10;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
exports.KNXnetIP = KNXnetIP;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* Apache Kafka wire protocol, TCP port 9092. Every Kafka message is length-prefixed: a big-endian uint32
|
|
6
|
+
* MessageSize counting the number of bytes that FOLLOW it, then the message. A REQUEST message begins with
|
|
7
|
+
* a request header — apiKey (2, BE) + apiVersion (2, BE) + correlationId (4, BE) + clientId (a nullable
|
|
8
|
+
* string: a 2-byte BE length, -1 meaning null, then that many UTF-8 bytes) + [tagged fields on flexible
|
|
9
|
+
* versions] + the request body. A RESPONSE begins with correlationId (4, BE) + body.
|
|
10
|
+
*
|
|
11
|
+
* ⚠️ Request vs response is NOT self-describing on the wire: telling them apart needs the paired
|
|
12
|
+
* connection state (which apiKey/apiVersion a given correlationId was requested with), which is
|
|
13
|
+
* cross-packet state — out of scope for this single-packet codec. This codec therefore assumes REQUEST
|
|
14
|
+
* framing: that is what a client sends, it is the more identifiable of the two (a response is just
|
|
15
|
+
* correlationId + opaque body), and it is the common client-side case. A captured response would be
|
|
16
|
+
* mis-labeled — a documented limitation of the minimal slice.
|
|
17
|
+
*
|
|
18
|
+
* As a REQUEST, this codec structures MessageSize + apiKey + apiVersion + correlationId and keeps the rest
|
|
19
|
+
* (clientId + optional tagged fields + body) verbatim as `payload` hex (byte-perfect), bounded by
|
|
20
|
+
* MessageSize (the message ends at offset 4 + MessageSize) and the captured bytes — so a pipelined second
|
|
21
|
+
* message or trailing bytes are left to the codec's recursion / RawData. The MessageSize is honored when
|
|
22
|
+
* supplied (a crafted message may lie), else derived as 8 (apiKey + apiVersion + correlationId) + payload
|
|
23
|
+
* bytes. A well-formed request round-trips byte-for-byte. Structuring clientId / tagged fields / the
|
|
24
|
+
* per-apiKey body is a later slice.
|
|
25
|
+
*/
|
|
26
|
+
export declare class Kafka 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,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Kafka = 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
|
+
/** Kafka's default socket.request.max.bytes (100 MiB). A MessageSize beyond this is implausible. */
|
|
11
|
+
const KAFKA_MAX_MESSAGE_SIZE = 104857600;
|
|
12
|
+
/**
|
|
13
|
+
* Apache Kafka wire protocol, TCP port 9092. Every Kafka message is length-prefixed: a big-endian uint32
|
|
14
|
+
* MessageSize counting the number of bytes that FOLLOW it, then the message. A REQUEST message begins with
|
|
15
|
+
* a request header — apiKey (2, BE) + apiVersion (2, BE) + correlationId (4, BE) + clientId (a nullable
|
|
16
|
+
* string: a 2-byte BE length, -1 meaning null, then that many UTF-8 bytes) + [tagged fields on flexible
|
|
17
|
+
* versions] + the request body. A RESPONSE begins with correlationId (4, BE) + body.
|
|
18
|
+
*
|
|
19
|
+
* ⚠️ Request vs response is NOT self-describing on the wire: telling them apart needs the paired
|
|
20
|
+
* connection state (which apiKey/apiVersion a given correlationId was requested with), which is
|
|
21
|
+
* cross-packet state — out of scope for this single-packet codec. This codec therefore assumes REQUEST
|
|
22
|
+
* framing: that is what a client sends, it is the more identifiable of the two (a response is just
|
|
23
|
+
* correlationId + opaque body), and it is the common client-side case. A captured response would be
|
|
24
|
+
* mis-labeled — a documented limitation of the minimal slice.
|
|
25
|
+
*
|
|
26
|
+
* As a REQUEST, this codec structures MessageSize + apiKey + apiVersion + correlationId and keeps the rest
|
|
27
|
+
* (clientId + optional tagged fields + body) verbatim as `payload` hex (byte-perfect), bounded by
|
|
28
|
+
* MessageSize (the message ends at offset 4 + MessageSize) and the captured bytes — so a pipelined second
|
|
29
|
+
* message or trailing bytes are left to the codec's recursion / RawData. The MessageSize is honored when
|
|
30
|
+
* supplied (a crafted message may lie), else derived as 8 (apiKey + apiVersion + correlationId) + payload
|
|
31
|
+
* bytes. A well-formed request round-trips byte-for-byte. Structuring clientId / tagged fields / the
|
|
32
|
+
* per-apiKey body is a later slice.
|
|
33
|
+
*/
|
|
34
|
+
class Kafka extends BaseHeader_1.BaseHeader {
|
|
35
|
+
constructor() {
|
|
36
|
+
super(...arguments);
|
|
37
|
+
this.id = 'kafka';
|
|
38
|
+
this.name = 'Kafka';
|
|
39
|
+
this.nickname = 'Kafka';
|
|
40
|
+
this.matchKeys = ['tcpport:9092'];
|
|
41
|
+
//A leaf header — clientId / tagged fields / the per-apiKey body require flexible-version and
|
|
42
|
+
//cross-message parsing kept verbatim as payload for now.
|
|
43
|
+
this.demuxProducers = [];
|
|
44
|
+
}
|
|
45
|
+
static #schemaCache;
|
|
46
|
+
get SCHEMA() {
|
|
47
|
+
return (Kafka.#schemaCache ??= Kafka.#buildSchema());
|
|
48
|
+
}
|
|
49
|
+
static #buildSchema() {
|
|
50
|
+
return {
|
|
51
|
+
type: 'object',
|
|
52
|
+
summary: 'Kafka apiKey=${apiKey}',
|
|
53
|
+
properties: {
|
|
54
|
+
//Big-endian uint32: the count of bytes that FOLLOW this field (apiKey + apiVersion +
|
|
55
|
+
//correlationId + payload). Honored when supplied (a crafted message may lie); else derived
|
|
56
|
+
//as 8 (the fixed apiKey + apiVersion + correlationId header) + payload bytes.
|
|
57
|
+
messageSize: {
|
|
58
|
+
type: 'integer',
|
|
59
|
+
label: 'Message Size',
|
|
60
|
+
minimum: 0,
|
|
61
|
+
maximum: 4294967295,
|
|
62
|
+
decode: function () {
|
|
63
|
+
this.instance.messageSize.setValue((0, BufferToNumber_1.BufferToUInt32)(this.readBytes(0, 4)));
|
|
64
|
+
},
|
|
65
|
+
encode: function () {
|
|
66
|
+
const provided = this.instance.messageSize.getValue();
|
|
67
|
+
let value = (provided !== undefined && provided !== null)
|
|
68
|
+
? provided
|
|
69
|
+
: 8 + (0, HexToBuffer_1.HexToBuffer)(this.instance.payload.getValue('')).length;
|
|
70
|
+
if (value > 4294967295) {
|
|
71
|
+
this.recordError(this.instance.messageSize.getPath(), 'Maximum value is 4294967295');
|
|
72
|
+
value = 4294967295;
|
|
73
|
+
}
|
|
74
|
+
if (value < 0) {
|
|
75
|
+
this.recordError(this.instance.messageSize.getPath(), 'Minimum value is 0');
|
|
76
|
+
value = 0;
|
|
77
|
+
}
|
|
78
|
+
this.instance.messageSize.setValue(value);
|
|
79
|
+
this.writeBytes(0, (0, NumberToBuffer_1.UInt32ToBuffer)(value));
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
apiKey: this.fieldUInt('apiKey', 4, 2, 'API Key'),
|
|
83
|
+
apiVersion: this.fieldUInt('apiVersion', 6, 2, 'API Version'),
|
|
84
|
+
correlationId: this.fieldUInt('correlationId', 8, 4, 'Correlation ID'),
|
|
85
|
+
//The rest of the request (clientId + optional tagged fields + body) after the 12-byte
|
|
86
|
+
//MessageSize/apiKey/apiVersion/correlationId prefix, kept verbatim. Bounded by MessageSize
|
|
87
|
+
//(the message ends at offset 4 + MessageSize) and the captured bytes, so trailing/pipelined
|
|
88
|
+
//data is left to the codec's recursion / RawData.
|
|
89
|
+
payload: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
label: 'Payload',
|
|
92
|
+
contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX,
|
|
93
|
+
decode: function () {
|
|
94
|
+
const remaining = this.packet.length - this.startPos;
|
|
95
|
+
const messageSize = this.instance.messageSize.getValue(0);
|
|
96
|
+
let end = 4 + messageSize;
|
|
97
|
+
if (end > remaining)
|
|
98
|
+
end = remaining;
|
|
99
|
+
this.instance.payload.setValue(end > 12 ? (0, BufferToHex_1.BufferToHex)(this.readBytes(12, end - 12)) : '');
|
|
100
|
+
},
|
|
101
|
+
encode: function () {
|
|
102
|
+
const payload = this.instance.payload.getValue('');
|
|
103
|
+
if (payload)
|
|
104
|
+
this.writeBytes(12, (0, HexToBuffer_1.HexToBuffer)(payload));
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
match() {
|
|
111
|
+
//Kafka rides on TCP port 9092. The length prefix is a WEAK content signature (any big-endian
|
|
112
|
+
//uint32 followed by bytes looks like it), so this stays a port-bucket protocol: matchKeys only,
|
|
113
|
+
//NO heuristicFallback — we never claim Kafka off port 9092 on the strength of a plausible length.
|
|
114
|
+
//Within the bucket, require the full 12-byte minimal request header (MessageSize + apiKey +
|
|
115
|
+
//apiVersion + correlationId) and a plausible MessageSize (large enough to cover the 8-byte
|
|
116
|
+
//apiKey/apiVersion/correlationId that MessageSize counts, and not absurdly large) so non-Kafka
|
|
117
|
+
//traffic on 9092 falls through to raw.
|
|
118
|
+
if (!this.prevCodecModule || this.prevCodecModule.id !== 'tcp')
|
|
119
|
+
return false;
|
|
120
|
+
if (this.packet.length - this.startPos < 12)
|
|
121
|
+
return false;
|
|
122
|
+
const messageSize = (0, BufferToNumber_1.BufferToUInt32)(this.readBytes(0, 4, true));
|
|
123
|
+
if (messageSize < 8)
|
|
124
|
+
return false;
|
|
125
|
+
return messageSize <= KAFKA_MAX_MESSAGE_SIZE;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
exports.Kafka = Kafka;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* Kerberos v5 (RFC 4120), UDP + TCP port 88. A Kerberos message is a single BER-encoded ASN.1
|
|
6
|
+
* APPLICATION-tagged element: `<appTag> <BER length> <body>`, where the application tag names the
|
|
7
|
+
* message type — 0x6a AS-REQ(10), 0x6b AS-REP(11), 0x6c TGS-REQ(12), 0x6d TGS-REP(13), 0x6e AP-REQ(14),
|
|
8
|
+
* 0x6f AP-REP(15), 0x7e KRB-ERROR(30).
|
|
9
|
+
*
|
|
10
|
+
* Transport framing differs by L4: over UDP the message is the whole datagram (no prefix); over TCP a
|
|
11
|
+
* 4-byte big-endian length prefix (the number of message bytes that follow) precedes it (RFC 4120 §7.2.2).
|
|
12
|
+
* This header detects the transport via prevCodecModule.id and structures accordingly: TCP → recordLength
|
|
13
|
+
* (uint32 BE) then the app-tagged message; UDP → the message directly (recordLength absent).
|
|
14
|
+
*
|
|
15
|
+
* Byte-perfect strategy (minimal slice): structure the application tag (msgType) + the message's BER
|
|
16
|
+
* length, and keep the body verbatim as `body` hex, bounded by the decoded BER length. The BER length is
|
|
17
|
+
* re-derived in minimal definite form on encode (matching what KDCs emit), and the TCP recordLength is
|
|
18
|
+
* honored when supplied else derived as the encoded message length. Parsing the KDC-REQ / KDC-REP /
|
|
19
|
+
* KRB-ERROR body (pvno, padata, req-body, etc.) is a later enrichment.
|
|
20
|
+
*/
|
|
21
|
+
export declare class Kerberos extends BaseHeader {
|
|
22
|
+
#private;
|
|
23
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
24
|
+
readonly id: string;
|
|
25
|
+
readonly name: string;
|
|
26
|
+
readonly nickname: string;
|
|
27
|
+
readonly matchKeys: string[];
|
|
28
|
+
match(): boolean;
|
|
29
|
+
readonly demuxProducers: DemuxProducer[];
|
|
30
|
+
}
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Kerberos = 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
|
+
* The set of Kerberos v5 application tags (RFC 4120 §5.4/5.5/5.9): AS-REQ [APPLICATION 10] = 0x6a,
|
|
12
|
+
* AS-REP 0x6b, TGS-REQ 0x6c, TGS-REP 0x6d, AP-REQ 0x6e, AP-REP 0x6f, KRB-ERROR [APPLICATION 30] = 0x7e.
|
|
13
|
+
* (0x6a = 0x60 | 10, 0x7e = 0x60 | 30 — application-class, constructed BER tags.)
|
|
14
|
+
*/
|
|
15
|
+
const KERBEROS_APP_TAGS = new Set([0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, 0x7e]);
|
|
16
|
+
/**
|
|
17
|
+
* Kerberos v5 (RFC 4120), UDP + TCP port 88. A Kerberos message is a single BER-encoded ASN.1
|
|
18
|
+
* APPLICATION-tagged element: `<appTag> <BER length> <body>`, where the application tag names the
|
|
19
|
+
* message type — 0x6a AS-REQ(10), 0x6b AS-REP(11), 0x6c TGS-REQ(12), 0x6d TGS-REP(13), 0x6e AP-REQ(14),
|
|
20
|
+
* 0x6f AP-REP(15), 0x7e KRB-ERROR(30).
|
|
21
|
+
*
|
|
22
|
+
* Transport framing differs by L4: over UDP the message is the whole datagram (no prefix); over TCP a
|
|
23
|
+
* 4-byte big-endian length prefix (the number of message bytes that follow) precedes it (RFC 4120 §7.2.2).
|
|
24
|
+
* This header detects the transport via prevCodecModule.id and structures accordingly: TCP → recordLength
|
|
25
|
+
* (uint32 BE) then the app-tagged message; UDP → the message directly (recordLength absent).
|
|
26
|
+
*
|
|
27
|
+
* Byte-perfect strategy (minimal slice): structure the application tag (msgType) + the message's BER
|
|
28
|
+
* length, and keep the body verbatim as `body` hex, bounded by the decoded BER length. The BER length is
|
|
29
|
+
* re-derived in minimal definite form on encode (matching what KDCs emit), and the TCP recordLength is
|
|
30
|
+
* honored when supplied else derived as the encoded message length. Parsing the KDC-REQ / KDC-REP /
|
|
31
|
+
* KRB-ERROR body (pvno, padata, req-body, etc.) is a later enrichment.
|
|
32
|
+
*/
|
|
33
|
+
class Kerberos extends BaseHeader_1.BaseHeader {
|
|
34
|
+
constructor() {
|
|
35
|
+
super(...arguments);
|
|
36
|
+
this.id = 'kerberos';
|
|
37
|
+
this.name = 'Kerberos';
|
|
38
|
+
this.nickname = 'Kerberos';
|
|
39
|
+
//KDC ports 88 on both UDP and TCP.
|
|
40
|
+
this.matchKeys = ['tcpport:88', 'udpport:88'];
|
|
41
|
+
//A leaf header — the KDC-REQ / KDC-REP / KRB-ERROR body is kept verbatim for now.
|
|
42
|
+
this.demuxProducers = [];
|
|
43
|
+
}
|
|
44
|
+
static #schemaCache;
|
|
45
|
+
get SCHEMA() {
|
|
46
|
+
return (Kerberos.#schemaCache ??= Kerberos.#buildSchema());
|
|
47
|
+
}
|
|
48
|
+
// ===== Minimal BER length codec (definite length only) =====
|
|
49
|
+
/** Read one TLV at `pos`; defensive against truncation (always advances, clamps to buffer). */
|
|
50
|
+
static #readTLV(buf, pos) {
|
|
51
|
+
if (pos >= buf.length)
|
|
52
|
+
return { tag: 0, contentStart: pos, contentLen: 0, next: pos + 1 };
|
|
53
|
+
const tag = buf[pos];
|
|
54
|
+
let p = pos + 1;
|
|
55
|
+
let len = p < buf.length ? buf[p] : 0;
|
|
56
|
+
p += 1;
|
|
57
|
+
if (len & 0x80) {
|
|
58
|
+
const lengthBytes = len & 0x7f;
|
|
59
|
+
len = 0;
|
|
60
|
+
for (let i = 0; i < lengthBytes; i++) {
|
|
61
|
+
len = len * 256 + (p < buf.length ? buf[p] : 0);
|
|
62
|
+
p += 1;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
const contentStart = p;
|
|
66
|
+
//Clamp the content to what is actually present so a lying length cannot read out of bounds.
|
|
67
|
+
const contentLen = Math.min(len, Math.max(0, buf.length - contentStart));
|
|
68
|
+
return { tag: tag, contentStart: contentStart, contentLen: contentLen, next: contentStart + contentLen };
|
|
69
|
+
}
|
|
70
|
+
/** Encode a definite length in minimal form (short form < 128, else long form). */
|
|
71
|
+
static #encodeLength(length) {
|
|
72
|
+
if (length < 0x80)
|
|
73
|
+
return Buffer.from([length]);
|
|
74
|
+
const bytes = [];
|
|
75
|
+
let v = length;
|
|
76
|
+
while (v > 0) {
|
|
77
|
+
bytes.unshift(v & 0xff);
|
|
78
|
+
v = Math.floor(v / 256);
|
|
79
|
+
}
|
|
80
|
+
return Buffer.from([0x80 | bytes.length, ...bytes]);
|
|
81
|
+
}
|
|
82
|
+
/** Offset of the app-tagged message within this header: 4 bytes past startPos for TCP, 0 for UDP. */
|
|
83
|
+
#messageOffset() {
|
|
84
|
+
return this.prevCodecModule && this.prevCodecModule.id === 'tcp' ? 4 : 0;
|
|
85
|
+
}
|
|
86
|
+
static #buildSchema() {
|
|
87
|
+
return {
|
|
88
|
+
type: 'object',
|
|
89
|
+
summary: 'Kerberos msgType=${msgType}',
|
|
90
|
+
properties: {
|
|
91
|
+
//TCP-only 4-byte big-endian length prefix (RFC 4120 §7.2.2): the number of message bytes
|
|
92
|
+
//that follow. Over UDP there is no prefix, so this field decodes/encodes nothing (the
|
|
93
|
+
//transport is detected via prevCodecModule.id). Honored when supplied (a crafted frame may
|
|
94
|
+
//lie); else derived at self-post-encode time as the encoded message length.
|
|
95
|
+
recordLength: {
|
|
96
|
+
type: 'integer',
|
|
97
|
+
label: 'Record Length',
|
|
98
|
+
minimum: 0,
|
|
99
|
+
maximum: 4294967295,
|
|
100
|
+
decode: function () {
|
|
101
|
+
if (!(this.prevCodecModule && this.prevCodecModule.id === 'tcp'))
|
|
102
|
+
return;
|
|
103
|
+
this.instance.recordLength.setValue((0, BufferToNumber_1.BufferToUInt32)(this.readBytes(0, 4)));
|
|
104
|
+
},
|
|
105
|
+
encode: function () {
|
|
106
|
+
if (!(this.prevCodecModule && this.prevCodecModule.id === 'tcp'))
|
|
107
|
+
return;
|
|
108
|
+
const provided = this.instance.recordLength.getValue();
|
|
109
|
+
if (provided !== undefined && provided !== null) {
|
|
110
|
+
let value = provided;
|
|
111
|
+
if (value > 4294967295) {
|
|
112
|
+
this.recordError(this.instance.recordLength.getPath(), 'Maximum value is 4294967295');
|
|
113
|
+
value = 4294967295;
|
|
114
|
+
}
|
|
115
|
+
if (value < 0) {
|
|
116
|
+
this.recordError(this.instance.recordLength.getPath(), 'Minimum value is 0');
|
|
117
|
+
value = 0;
|
|
118
|
+
}
|
|
119
|
+
this.instance.recordLength.setValue(value);
|
|
120
|
+
this.writeBytes(0, (0, NumberToBuffer_1.UInt32ToBuffer)(value));
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
//Derive after the message bytes have been written: the record length counts
|
|
124
|
+
//exactly the app-tagged message (everything after this 4-byte prefix).
|
|
125
|
+
this.writeBytes(0, (0, NumberToBuffer_1.UInt32ToBuffer)(0));
|
|
126
|
+
this.addPostSelfEncodeHandler(() => {
|
|
127
|
+
const messageLength = this.headerLength - 4;
|
|
128
|
+
const value = messageLength > 0 ? messageLength : 0;
|
|
129
|
+
this.instance.recordLength.setValue(value);
|
|
130
|
+
this.writeBytes(0, (0, NumberToBuffer_1.UInt32ToBuffer)(value));
|
|
131
|
+
}, 0);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
},
|
|
135
|
+
//The message-type application tag (0x6a AS-REQ … 0x7e KRB-ERROR). It is the outer BER tag
|
|
136
|
+
//of the message, so it is decoded/re-emitted together with the BER length and body below.
|
|
137
|
+
msgType: {
|
|
138
|
+
type: 'integer',
|
|
139
|
+
label: 'Message Type',
|
|
140
|
+
minimum: 0,
|
|
141
|
+
maximum: 255,
|
|
142
|
+
decode: function () {
|
|
143
|
+
const messageOffset = this.#messageOffset();
|
|
144
|
+
const available = this.packet.length - this.startPos - messageOffset;
|
|
145
|
+
if (available <= 0)
|
|
146
|
+
return;
|
|
147
|
+
//Read enough to cover the tag + BER length header, then the whole message so
|
|
148
|
+
//headerLength/endPos span exactly this Kerberos message (the TCP prefix included).
|
|
149
|
+
const headerPeek = available < 6 ? available : 6;
|
|
150
|
+
const peek = this.readBytes(messageOffset, headerPeek, true);
|
|
151
|
+
this.instance.msgType.setValue(peek.length > 0 ? peek[0] : 0);
|
|
152
|
+
//Parse the BER length from the peek (unclamped — the peek is only the header, so
|
|
153
|
+
//#readTLV's content clamp would wrongly cap the total message length).
|
|
154
|
+
let lp = 1;
|
|
155
|
+
let declaredLength = lp < peek.length ? peek[lp] : 0;
|
|
156
|
+
lp += 1;
|
|
157
|
+
if (declaredLength & 0x80) {
|
|
158
|
+
const lengthBytes = declaredLength & 0x7f;
|
|
159
|
+
declaredLength = 0;
|
|
160
|
+
for (let i = 0; i < lengthBytes; i++) {
|
|
161
|
+
declaredLength = declaredLength * 256 + (lp < peek.length ? peek[lp] : 0);
|
|
162
|
+
lp += 1;
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
const total = Math.min(lp + declaredLength, available);
|
|
166
|
+
//Read the full message (non-dry-run) to set headerLength; then split off the body.
|
|
167
|
+
const message = this.readBytes(messageOffset, total > 0 ? total : 0);
|
|
168
|
+
const tlv = Kerberos.#readTLV(message, 0);
|
|
169
|
+
this.instance.body.setValue((0, BufferToHex_1.BufferToHex)(message.subarray(tlv.contentStart, tlv.next)));
|
|
170
|
+
},
|
|
171
|
+
encode: function () {
|
|
172
|
+
const messageOffset = this.#messageOffset();
|
|
173
|
+
let msgType = this.instance.msgType.getValue(0x6a);
|
|
174
|
+
if (msgType > 255) {
|
|
175
|
+
this.recordError(this.instance.msgType.getPath(), 'Maximum value is 255');
|
|
176
|
+
msgType = 255;
|
|
177
|
+
}
|
|
178
|
+
if (msgType < 0) {
|
|
179
|
+
this.recordError(this.instance.msgType.getPath(), 'Minimum value is 0');
|
|
180
|
+
msgType = 0;
|
|
181
|
+
}
|
|
182
|
+
this.instance.msgType.setValue(msgType);
|
|
183
|
+
const body = (0, HexToBuffer_1.HexToBuffer)(this.instance.body.getValue(''));
|
|
184
|
+
const message = Buffer.concat([
|
|
185
|
+
Buffer.from([msgType]),
|
|
186
|
+
Kerberos.#encodeLength(body.length),
|
|
187
|
+
body
|
|
188
|
+
]);
|
|
189
|
+
this.writeBytes(messageOffset, message);
|
|
190
|
+
}
|
|
191
|
+
},
|
|
192
|
+
//The message body: everything inside the application tag's BER length, kept verbatim.
|
|
193
|
+
//Emitted by the msgType closure (colocated so the tag + length + body stay symmetric).
|
|
194
|
+
body: { type: 'string', label: 'Body', contentEncoding: StringContentEncodingEnum_1.StringContentEncodingEnum.HEX }
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
match() {
|
|
199
|
+
//Kerberos rides UDP/TCP port 88 (selected via the udpport:88 / tcpport:88 buckets). The signature
|
|
200
|
+
//is port + a Kerberos application tag at the message start, so this stays a port-bucket protocol:
|
|
201
|
+
//matchKeys only, NO heuristicFallback — an application-class BER tag alone is too weak to claim
|
|
202
|
+
//Kerberos off port 88, and non-Kerberos traffic on 88 must fall through to raw. Over TCP the tag
|
|
203
|
+
//sits after the 4-byte record-length prefix; over UDP it is the first byte.
|
|
204
|
+
if (!this.prevCodecModule)
|
|
205
|
+
return false;
|
|
206
|
+
const isTcp = this.prevCodecModule.id === 'tcp';
|
|
207
|
+
const isUdp = this.prevCodecModule.id === 'udp';
|
|
208
|
+
if (!isTcp && !isUdp)
|
|
209
|
+
return false;
|
|
210
|
+
const messageOffset = isTcp ? 4 : 0;
|
|
211
|
+
if (this.packet.length - this.startPos < messageOffset + 2)
|
|
212
|
+
return false;
|
|
213
|
+
const tag = this.readBytes(messageOffset, 1, true)[0];
|
|
214
|
+
return KERBEROS_APP_TAGS.has(tag);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
exports.Kerberos = Kerberos;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { BaseHeader } from '../abstracts/BaseHeader';
|
|
2
|
+
import { ProtocolJSONSchema } from '../schema/ProtocolJSONSchema';
|
|
3
|
+
import { DemuxProducer } from '../types/DemuxProducer';
|
|
4
|
+
/**
|
|
5
|
+
* L2TP — Layer Two Tunneling Protocol, version 2 (RFC 2661), UDP port 1701. The header begins with a
|
|
6
|
+
* 2-byte flags/version field: T (0=data / 1=control), L (Length present), S (Ns/Nr present), O (Offset
|
|
7
|
+
* present), P (Priority), and a 4-bit Version (=2). Depending on the flags the header then carries an
|
|
8
|
+
* optional Length, the Tunnel ID and Session ID, optional Ns/Nr sequence numbers, and an optional
|
|
9
|
+
* Offset (size + pad). A control message (T=1) carries a list of AVPs (each: M/H flags + 10-bit length,
|
|
10
|
+
* Vendor ID, Attribute Type, value); a data message (T=0) carries the tunneled payload, kept as raw hex
|
|
11
|
+
* (it is a leaf here — the tunneled PPP frame is a stateful conversation for a higher layer).
|
|
12
|
+
*
|
|
13
|
+
* A well-formed message round-trips byte-for-byte. The reserved flag bits and AVP reserved bits are
|
|
14
|
+
* normalized to 0 on re-encode (they MUST be 0 per RFC 2661), and an AVP's length is derived from its
|
|
15
|
+
* value; both hold for standard-conformant traffic.
|
|
16
|
+
*/
|
|
17
|
+
export declare class L2TP extends BaseHeader {
|
|
18
|
+
#private;
|
|
19
|
+
get SCHEMA(): ProtocolJSONSchema;
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly name: string;
|
|
22
|
+
readonly nickname: string;
|
|
23
|
+
readonly matchKeys: string[];
|
|
24
|
+
match(): boolean;
|
|
25
|
+
readonly demuxProducers: DemuxProducer[];
|
|
26
|
+
}
|