Takahiro Suzuki | d7bf820 | 2020-12-17 20:21:59 +0900 | [diff] [blame^] | 1 | // 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 | |
| 7 | package layers |
| 8 | |
| 9 | import ( |
| 10 | "encoding/binary" |
| 11 | "github.com/google/gopacket" |
| 12 | "net" |
| 13 | "strconv" |
| 14 | ) |
| 15 | |
| 16 | var ( |
| 17 | // We use two different endpoint types for IPv4 vs IPv6 addresses, so that |
| 18 | // ordering with endpointA.LessThan(endpointB) sanely groups all IPv4 |
| 19 | // addresses and all IPv6 addresses, such that IPv6 > IPv4 for all addresses. |
| 20 | EndpointIPv4 = gopacket.RegisterEndpointType(1, gopacket.EndpointTypeMetadata{Name: "IPv4", Formatter: func(b []byte) string { |
| 21 | return net.IP(b).String() |
| 22 | }}) |
| 23 | EndpointIPv6 = gopacket.RegisterEndpointType(2, gopacket.EndpointTypeMetadata{Name: "IPv6", Formatter: func(b []byte) string { |
| 24 | return net.IP(b).String() |
| 25 | }}) |
| 26 | |
| 27 | EndpointMAC = gopacket.RegisterEndpointType(3, gopacket.EndpointTypeMetadata{Name: "MAC", Formatter: func(b []byte) string { |
| 28 | return net.HardwareAddr(b).String() |
| 29 | }}) |
| 30 | EndpointTCPPort = gopacket.RegisterEndpointType(4, gopacket.EndpointTypeMetadata{Name: "TCP", Formatter: func(b []byte) string { |
| 31 | return strconv.Itoa(int(binary.BigEndian.Uint16(b))) |
| 32 | }}) |
| 33 | EndpointUDPPort = gopacket.RegisterEndpointType(5, gopacket.EndpointTypeMetadata{Name: "UDP", Formatter: func(b []byte) string { |
| 34 | return strconv.Itoa(int(binary.BigEndian.Uint16(b))) |
| 35 | }}) |
| 36 | EndpointSCTPPort = gopacket.RegisterEndpointType(6, gopacket.EndpointTypeMetadata{Name: "SCTP", Formatter: func(b []byte) string { |
| 37 | return strconv.Itoa(int(binary.BigEndian.Uint16(b))) |
| 38 | }}) |
| 39 | EndpointRUDPPort = gopacket.RegisterEndpointType(7, gopacket.EndpointTypeMetadata{Name: "RUDP", Formatter: func(b []byte) string { |
| 40 | return strconv.Itoa(int(b[0])) |
| 41 | }}) |
| 42 | EndpointUDPLitePort = gopacket.RegisterEndpointType(8, gopacket.EndpointTypeMetadata{Name: "UDPLite", Formatter: func(b []byte) string { |
| 43 | return strconv.Itoa(int(binary.BigEndian.Uint16(b))) |
| 44 | }}) |
| 45 | EndpointPPP = gopacket.RegisterEndpointType(9, gopacket.EndpointTypeMetadata{Name: "PPP", Formatter: func([]byte) string { |
| 46 | return "point" |
| 47 | }}) |
| 48 | ) |
| 49 | |
| 50 | // NewIPEndpoint creates a new IP (v4 or v6) endpoint from a net.IP address. |
| 51 | // It returns gopacket.InvalidEndpoint if the IP address is invalid. |
| 52 | func NewIPEndpoint(a net.IP) gopacket.Endpoint { |
| 53 | ipv4 := a.To4() |
| 54 | if ipv4 != nil { |
| 55 | return gopacket.NewEndpoint(EndpointIPv4, []byte(ipv4)) |
| 56 | } |
| 57 | |
| 58 | ipv6 := a.To16() |
| 59 | if ipv6 != nil { |
| 60 | return gopacket.NewEndpoint(EndpointIPv6, []byte(ipv6)) |
| 61 | } |
| 62 | |
| 63 | return gopacket.InvalidEndpoint |
| 64 | } |
| 65 | |
| 66 | // NewMACEndpoint returns a new MAC address endpoint. |
| 67 | func NewMACEndpoint(a net.HardwareAddr) gopacket.Endpoint { |
| 68 | return gopacket.NewEndpoint(EndpointMAC, []byte(a)) |
| 69 | } |
| 70 | func newPortEndpoint(t gopacket.EndpointType, p uint16) gopacket.Endpoint { |
| 71 | return gopacket.NewEndpoint(t, []byte{byte(p >> 8), byte(p)}) |
| 72 | } |
| 73 | |
| 74 | // NewTCPPortEndpoint returns an endpoint based on a TCP port. |
| 75 | func NewTCPPortEndpoint(p TCPPort) gopacket.Endpoint { |
| 76 | return newPortEndpoint(EndpointTCPPort, uint16(p)) |
| 77 | } |
| 78 | |
| 79 | // NewUDPPortEndpoint returns an endpoint based on a UDP port. |
| 80 | func NewUDPPortEndpoint(p UDPPort) gopacket.Endpoint { |
| 81 | return newPortEndpoint(EndpointUDPPort, uint16(p)) |
| 82 | } |
| 83 | |
| 84 | // NewSCTPPortEndpoint returns an endpoint based on a SCTP port. |
| 85 | func NewSCTPPortEndpoint(p SCTPPort) gopacket.Endpoint { |
| 86 | return newPortEndpoint(EndpointSCTPPort, uint16(p)) |
| 87 | } |
| 88 | |
| 89 | // NewRUDPPortEndpoint returns an endpoint based on a RUDP port. |
| 90 | func NewRUDPPortEndpoint(p RUDPPort) gopacket.Endpoint { |
| 91 | return gopacket.NewEndpoint(EndpointRUDPPort, []byte{byte(p)}) |
| 92 | } |
| 93 | |
| 94 | // NewUDPLitePortEndpoint returns an endpoint based on a UDPLite port. |
| 95 | func NewUDPLitePortEndpoint(p UDPLitePort) gopacket.Endpoint { |
| 96 | return newPortEndpoint(EndpointUDPLitePort, uint16(p)) |
| 97 | } |