22package layers
33
44import (
5+ "bytes"
6+ "encoding/binary"
57 "fmt"
8+ "net/netip"
69 "unsafe"
710)
811
912const maxLenSummary = 110
1013
11- var LayerMap = map [ string ] Layer {
12- "ETH" : & EthernetFrame {} ,
13- "IPv4" : & IPv4Packet {} ,
14- "IPv6" : & IPv6Packet {} ,
15- "ARP" : & ARPPacket {} ,
16- "TCP" : & TCPSegment {} ,
17- "UDP" : & UDPSegment {} ,
18- "ICMP" : & ICMPSegment {} ,
19- "ICMPv6" : & ICMPv6Segment {} ,
20- "DNS" : & DNSMessage {} ,
21- "FTP" : & FTPMessage {} ,
22- "HTTP" : & HTTPMessage {} ,
23- "SNMP" : & SNMPMessage {} ,
24- "SSH" : & SSHMessage {} ,
25- "TLS" : & TLSMessage {} ,
14+ var Layers = [] string {
15+ "ETH" ,
16+ "IPv4" ,
17+ "IPv6" ,
18+ "ARP" ,
19+ "TCP" ,
20+ "UDP" ,
21+ "ICMP" ,
22+ "ICMPv6" ,
23+ "DNS" ,
24+ "FTP" ,
25+ "HTTP" ,
26+ "SNMP" ,
27+ "SSH" ,
28+ "TLS" ,
2629}
2730
2831var (
@@ -46,6 +49,129 @@ type Layer interface {
4649 Summary () string
4750}
4851
52+ func parseNextLayerFallback (data []byte ) Layer {
53+ for _ , layer := range Layers {
54+ next := GetNextLayer (layer )
55+ if err := next .Parse (data ); err == nil {
56+ return next
57+ }
58+ }
59+ return nil
60+ }
61+
62+ func parseNextLayerFromBytes (data []byte ) Layer {
63+ buf := make ([]byte , 0 , len (data ))
64+ buf = append (buf , data ... )
65+ var next Layer
66+ firstByte := buf [0 ]
67+ if firstByte >= 0x45 && firstByte <= 0x4F {
68+ next = GetNextLayer ("IPv4" )
69+ if err := next .Parse (buf ); err == nil {
70+ return next
71+ }
72+ }
73+ if firstByte >> 4 == 6 {
74+ next = GetNextLayer ("IPv6" )
75+ if err := next .Parse (buf ); err == nil {
76+ return next
77+ }
78+ }
79+ if firstByte == HandshakeTLSVal {
80+ next = GetNextLayer ("TLS" )
81+ if err := next .Parse (buf ); err == nil {
82+ return next
83+ }
84+ }
85+ if len (buf ) > 3 {
86+ b1 := binary .BigEndian .Uint16 (buf [0 :2 ])
87+ b2 := binary .BigEndian .Uint16 (buf [2 :4 ])
88+ if b1 == 1 && (b2 == 0x0800 || b2 == 0x86dd ) {
89+ next = GetNextLayer ("ARP" )
90+ if err := next .Parse (buf ); err == nil {
91+ return next
92+ }
93+ }
94+ }
95+ if len (buf ) > 15 {
96+ b1 := binary .BigEndian .Uint16 (buf [12 :14 ])
97+ if b1 == 0x0806 || b1 == 0x0800 || b1 == 0x86dd {
98+ next = GetNextLayer ("ETH" )
99+ if err := next .Parse (buf ); err == nil {
100+ return next
101+ }
102+ }
103+ }
104+ if bytes .Contains (buf , protohttp10 ) || bytes .Contains (buf , protohttp11 ) {
105+ next = GetNextLayer ("HTTP" )
106+ if err := next .Parse (buf ); err == nil {
107+ return next
108+ }
109+ }
110+ if bytes .Contains (buf , protoSSH ) {
111+ next = GetNextLayer ("SSH" )
112+ if err := next .Parse (buf ); err == nil {
113+ return next
114+ }
115+ }
116+ return nil
117+ }
118+
119+ func addrMatch (src , dst * netip.AddrPort , ports []uint16 ) bool {
120+ var srcPort , dstPort uint16
121+ if src != nil {
122+ srcPort = src .Port ()
123+ }
124+ if dst != nil {
125+ dstPort = src .Port ()
126+ }
127+ for _ , port := range ports {
128+ if srcPort == port || dstPort == port {
129+ return true
130+ }
131+ }
132+ return false
133+ }
134+
135+ func parseNextLayerFromAddress (data []byte , src , dst * netip.AddrPort ) Layer {
136+ var next Layer
137+ switch {
138+ case addrMatch (src , dst , []uint16 {53 , 5353 , 853 , 5355 }):
139+ next = GetNextLayer ("DNS" )
140+ case addrMatch (src , dst , []uint16 {80 , 8080 , 8000 , 8888 , 81 , 591 , 5911 }):
141+ next = GetNextLayer ("HTTP" )
142+ case addrMatch (src , dst , []uint16 {161 , 162 , 10161 , 10162 , 1161 , 2161 }):
143+ next = GetNextLayer ("SNMP" )
144+ case addrMatch (src , dst , []uint16 {21 , 20 , 2121 , 8021 }):
145+ next = GetNextLayer ("FTP" )
146+ case addrMatch (src , dst , []uint16 {22 , 2222 , 2200 , 222 , 2022 }):
147+ next = GetNextLayer ("SSH" )
148+ case addrMatch (src , dst , []uint16 {443 , 465 , 993 , 995 , 8443 , 9443 , 10443 , 8444 }):
149+ next = GetNextLayer ("TLS" )
150+ default :
151+ return nil
152+ }
153+ if err := next .Parse (data ); err == nil {
154+ return next
155+ } else {
156+ return nil
157+ }
158+ }
159+
160+ func ParseNextLayer (data []byte , src , dst * netip.AddrPort ) Layer {
161+ buf := make ([]byte , 0 , len (data ))
162+ buf = append (buf , data ... )
163+ var next Layer
164+ if src != nil || dst != nil {
165+ if next = parseNextLayerFromAddress (buf , src , dst ); next != nil {
166+ return next
167+ }
168+ }
169+ if next = parseNextLayerFromBytes (buf ); next != nil {
170+ return next
171+ }
172+ return parseNextLayerFallback (buf )
173+ }
174+
49175func GetNextLayer (layer string ) Layer {
50176 // TODO (shadowy-pycoder): add this to NextLayer, choose by ports, parse, use fallback on error
51177 switch layer {
0 commit comments