1package proxyproto
2
3// AddressFamilyAndProtocol represents address family and transport protocol.
4type AddressFamilyAndProtocol byte
5
6const (
7	UNSPEC       AddressFamilyAndProtocol = '\x00'
8	TCPv4        AddressFamilyAndProtocol = '\x11'
9	UDPv4        AddressFamilyAndProtocol = '\x12'
10	TCPv6        AddressFamilyAndProtocol = '\x21'
11	UDPv6        AddressFamilyAndProtocol = '\x22'
12	UnixStream   AddressFamilyAndProtocol = '\x31'
13	UnixDatagram AddressFamilyAndProtocol = '\x32'
14)
15
16var supportedTransportProtocol = map[AddressFamilyAndProtocol]bool{
17	TCPv4:        true,
18	UDPv4:        true,
19	TCPv6:        true,
20	UDPv6:        true,
21	UnixStream:   true,
22	UnixDatagram: true,
23}
24
25// IsIPv4 returns true if the address family is IPv4 (AF_INET4), false otherwise.
26func (ap AddressFamilyAndProtocol) IsIPv4() bool {
27	return 0x10 == ap&0xF0
28}
29
30// IsIPv6 returns true if the address family is IPv6 (AF_INET6), false otherwise.
31func (ap AddressFamilyAndProtocol) IsIPv6() bool {
32	return 0x20 == ap&0xF0
33}
34
35// IsUnix returns true if the address family is UNIX (AF_UNIX), false otherwise.
36func (ap AddressFamilyAndProtocol) IsUnix() bool {
37	return 0x30 == ap&0xF0
38}
39
40// IsStream returns true if the transport protocol is TCP or STREAM (SOCK_STREAM), false otherwise.
41func (ap AddressFamilyAndProtocol) IsStream() bool {
42	return 0x01 == ap&0x0F
43}
44
45// IsDatagram returns true if the transport protocol is UDP or DGRAM (SOCK_DGRAM), false otherwise.
46func (ap AddressFamilyAndProtocol) IsDatagram() bool {
47	return 0x02 == ap&0x0F
48}
49
50// IsUnspec returns true if the transport protocol or address family is unspecified, false otherwise.
51func (ap AddressFamilyAndProtocol) IsUnspec() bool {
52	return (0x00 == ap&0xF0) || (0x00 == ap&0x0F)
53}
54
55func (ap AddressFamilyAndProtocol) toByte() byte {
56	if ap.IsIPv4() && ap.IsStream() {
57		return byte(TCPv4)
58	} else if ap.IsIPv4() && ap.IsDatagram() {
59		return byte(UDPv4)
60	} else if ap.IsIPv6() && ap.IsStream() {
61		return byte(TCPv6)
62	} else if ap.IsIPv6() && ap.IsDatagram() {
63		return byte(UDPv6)
64	} else if ap.IsUnix() && ap.IsStream() {
65		return byte(UnixStream)
66	} else if ap.IsUnix() && ap.IsDatagram() {
67		return byte(UnixDatagram)
68	}
69
70	return byte(UNSPEC)
71}
72