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
16// IsIPv4 returns true if the address family is IPv4 (AF_INET4), false otherwise.
17func (ap AddressFamilyAndProtocol) IsIPv4() bool {
18	return 0x10 == ap&0xF0
19}
20
21// IsIPv6 returns true if the address family is IPv6 (AF_INET6), false otherwise.
22func (ap AddressFamilyAndProtocol) IsIPv6() bool {
23	return 0x20 == ap&0xF0
24}
25
26// IsUnix returns true if the address family is UNIX (AF_UNIX), false otherwise.
27func (ap AddressFamilyAndProtocol) IsUnix() bool {
28	return 0x30 == ap&0xF0
29}
30
31// IsStream returns true if the transport protocol is TCP or STREAM (SOCK_STREAM), false otherwise.
32func (ap AddressFamilyAndProtocol) IsStream() bool {
33	return 0x01 == ap&0x0F
34}
35
36// IsDatagram returns true if the transport protocol is UDP or DGRAM (SOCK_DGRAM), false otherwise.
37func (ap AddressFamilyAndProtocol) IsDatagram() bool {
38	return 0x02 == ap&0x0F
39}
40
41// IsUnspec returns true if the transport protocol or address family is unspecified, false otherwise.
42func (ap AddressFamilyAndProtocol) IsUnspec() bool {
43	return (0x00 == ap&0xF0) || (0x00 == ap&0x0F)
44}
45
46func (ap AddressFamilyAndProtocol) toByte() byte {
47	if ap.IsIPv4() && ap.IsStream() {
48		return byte(TCPv4)
49	} else if ap.IsIPv4() && ap.IsDatagram() {
50		return byte(UDPv4)
51	} else if ap.IsIPv6() && ap.IsStream() {
52		return byte(TCPv6)
53	} else if ap.IsIPv6() && ap.IsDatagram() {
54		return byte(UDPv6)
55	} else if ap.IsUnix() && ap.IsStream() {
56		return byte(UnixStream)
57	} else if ap.IsUnix() && ap.IsDatagram() {
58		return byte(UnixDatagram)
59	}
60
61	return byte(UNSPEC)
62}
63