blob: 705fd1dbaf8d8ec3aa5ca0298009f97aaa816944 [file] [log] [blame]
Takahiro Suzuki241c10e2020-12-17 20:17:57 +09001// Copyright 2012 Google, Inc. All rights reserved.
2//
3// Use of this source code is governed by a BSD-style license
4// that can be found in the LICENSE file in the root of the source
5// tree.
6
7package layers
8
9import (
10 "fmt"
11 "strconv"
12
13 "github.com/google/gopacket"
14)
15
16// TCPPort is a port in a TCP layer.
17type TCPPort uint16
18
19// UDPPort is a port in a UDP layer.
20type UDPPort uint16
21
22// RUDPPort is a port in a RUDP layer.
23type RUDPPort uint8
24
25// SCTPPort is a port in a SCTP layer.
26type SCTPPort uint16
27
28// UDPLitePort is a port in a UDPLite layer.
29type UDPLitePort uint16
30
31// RUDPPortNames contains the string names for all RUDP ports.
32var RUDPPortNames = map[RUDPPort]string{}
33
34// UDPLitePortNames contains the string names for all UDPLite ports.
35var UDPLitePortNames = map[UDPLitePort]string{}
36
37// {TCP,UDP,SCTP}PortNames can be found in iana_ports.go
38
39// String returns the port as "number(name)" if there's a well-known port name,
40// or just "number" if there isn't. Well-known names are stored in
41// TCPPortNames.
42func (a TCPPort) String() string {
43 if name, ok := TCPPortNames[a]; ok {
44 return fmt.Sprintf("%d(%s)", a, name)
45 }
46 return strconv.Itoa(int(a))
47}
48
49// LayerType returns a LayerType that would be able to decode the
50// application payload. It uses some well-known ports such as 53 for
51// DNS.
52//
53// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers.
54func (a TCPPort) LayerType() gopacket.LayerType {
55 lt := tcpPortLayerType[uint16(a)]
56 if lt != 0 {
57 return lt
58 }
59 return gopacket.LayerTypePayload
60}
61
62var tcpPortLayerType = [65536]gopacket.LayerType{
63 53: LayerTypeDNS,
64 443: LayerTypeTLS, // https
65 502: LayerTypeModbusTCP, // modbustcp
66 636: LayerTypeTLS, // ldaps
67 989: LayerTypeTLS, // ftps-data
68 990: LayerTypeTLS, // ftps
69 992: LayerTypeTLS, // telnets
70 993: LayerTypeTLS, // imaps
71 994: LayerTypeTLS, // ircs
72 995: LayerTypeTLS, // pop3s
73 5061: LayerTypeTLS, // ips
74}
75
76// RegisterTCPPortLayerType creates a new mapping between a TCPPort
77// and an underlaying LayerType.
78func RegisterTCPPortLayerType(port TCPPort, layerType gopacket.LayerType) {
79 tcpPortLayerType[port] = layerType
80}
81
82// String returns the port as "number(name)" if there's a well-known port name,
83// or just "number" if there isn't. Well-known names are stored in
84// UDPPortNames.
85func (a UDPPort) String() string {
86 if name, ok := UDPPortNames[a]; ok {
87 return fmt.Sprintf("%d(%s)", a, name)
88 }
89 return strconv.Itoa(int(a))
90}
91
92// LayerType returns a LayerType that would be able to decode the
93// application payload. It uses some well-known ports such as 53 for
94// DNS.
95//
96// Returns gopacket.LayerTypePayload for unknown/unsupported port numbers.
97func (a UDPPort) LayerType() gopacket.LayerType {
98 lt := udpPortLayerType[uint16(a)]
99 if lt != 0 {
100 return lt
101 }
102 return gopacket.LayerTypePayload
103}
104
105var udpPortLayerType = [65536]gopacket.LayerType{
106 53: LayerTypeDNS,
107 123: LayerTypeNTP,
108 4789: LayerTypeVXLAN,
109 67: LayerTypeDHCPv4,
110 68: LayerTypeDHCPv4,
111 546: LayerTypeDHCPv6,
112 547: LayerTypeDHCPv6,
113 5060: LayerTypeSIP,
114 6343: LayerTypeSFlow,
115 6081: LayerTypeGeneve,
116 3784: LayerTypeBFD,
117 2152: LayerTypeGTPv1U,
118}
119
120// RegisterUDPPortLayerType creates a new mapping between a UDPPort
121// and an underlaying LayerType.
122func RegisterUDPPortLayerType(port UDPPort, layerType gopacket.LayerType) {
123 udpPortLayerType[port] = layerType
124}
125
126// String returns the port as "number(name)" if there's a well-known port name,
127// or just "number" if there isn't. Well-known names are stored in
128// RUDPPortNames.
129func (a RUDPPort) String() string {
130 if name, ok := RUDPPortNames[a]; ok {
131 return fmt.Sprintf("%d(%s)", a, name)
132 }
133 return strconv.Itoa(int(a))
134}
135
136// String returns the port as "number(name)" if there's a well-known port name,
137// or just "number" if there isn't. Well-known names are stored in
138// SCTPPortNames.
139func (a SCTPPort) String() string {
140 if name, ok := SCTPPortNames[a]; ok {
141 return fmt.Sprintf("%d(%s)", a, name)
142 }
143 return strconv.Itoa(int(a))
144}
145
146// String returns the port as "number(name)" if there's a well-known port name,
147// or just "number" if there isn't. Well-known names are stored in
148// UDPLitePortNames.
149func (a UDPLitePort) String() string {
150 if name, ok := UDPLitePortNames[a]; ok {
151 return fmt.Sprintf("%d(%s)", a, name)
152 }
153 return strconv.Itoa(int(a))
154}