1package garden
2
3import "net"
4
5type NetOutRule struct {
6	// the protocol to be whitelisted
7	Protocol Protocol `json:"protocol,omitempty"`
8
9	// a list of ranges of IP addresses to whitelist; Start to End inclusive; default all
10	Networks []IPRange `json:"networks,omitempty"`
11
12	// a list of ranges of ports to whitelist; Start to End inclusive; ignored if Protocol is ICMP; default all
13	Ports []PortRange `json:"ports,omitempty"`
14
15	// specifying which ICMP codes to whitelist; ignored if Protocol is not ICMP; default all
16	ICMPs *ICMPControl `json:"icmps,omitempty"`
17
18	// if true, logging is enabled; ignored if Protocol is not TCP or All; default false
19	Log bool `json:"log,omitempty"`
20}
21
22type Protocol uint8
23
24const (
25	ProtocolAll Protocol = iota
26	ProtocolTCP
27	ProtocolUDP
28	ProtocolICMP
29)
30
31type IPRange struct {
32	Start net.IP `json:"start,omitempty"`
33	End   net.IP `json:"end,omitempty"`
34}
35
36type PortRange struct {
37	Start uint16 `json:"start,omitempty"`
38	End   uint16 `json:"end,omitempty"`
39}
40
41type ICMPType uint8
42type ICMPCode uint8
43
44type ICMPControl struct {
45	Type ICMPType  `json:"type,omitempty"`
46	Code *ICMPCode `json:"code,omitempty"`
47}
48
49// IPRangeFromIP creates an IPRange containing a single IP
50func IPRangeFromIP(ip net.IP) IPRange {
51	return IPRange{Start: ip, End: ip}
52}
53
54// IPRangeFromIPNet creates an IPRange containing the same IPs as a given IPNet
55func IPRangeFromIPNet(ipNet *net.IPNet) IPRange {
56	return IPRange{Start: ipNet.IP, End: lastIP(ipNet)}
57}
58
59// PortRangeFromPort creates a PortRange containing a single port
60func PortRangeFromPort(port uint16) PortRange {
61	return PortRange{Start: port, End: port}
62}
63
64// ICMPControlCode creates a value for the Code field in ICMPControl
65func ICMPControlCode(code uint8) *ICMPCode {
66	pCode := ICMPCode(code)
67	return &pCode
68}
69
70// Last IP (broadcast) address in a network (net.IPNet)
71func lastIP(n *net.IPNet) net.IP {
72	mask := n.Mask
73	ip := n.IP
74	lastip := make(net.IP, len(ip))
75	// set bits zero in the mask to ones in ip
76	for i, m := range mask {
77		lastip[i] = (^m) | ip[i]
78	}
79	return lastip
80}
81