1package dns
2
3import (
4	"net"
5	"testing"
6)
7
8func TestOPTTtl(t *testing.T) {
9	e := &OPT{}
10	e.Hdr.Name = "."
11	e.Hdr.Rrtype = TypeOPT
12
13	// verify the default setting of DO=0
14	if e.Do() {
15		t.Errorf("DO bit should be zero")
16	}
17
18	// There are 6 possible invocations of SetDo():
19	//
20	// 1. Starting with DO=0, using SetDo()
21	// 2. Starting with DO=0, using SetDo(true)
22	// 3. Starting with DO=0, using SetDo(false)
23	// 4. Starting with DO=1, using SetDo()
24	// 5. Starting with DO=1, using SetDo(true)
25	// 6. Starting with DO=1, using SetDo(false)
26
27	// verify that invoking SetDo() sets DO=1 (TEST #1)
28	e.SetDo()
29	if !e.Do() {
30		t.Errorf("DO bit should be non-zero")
31	}
32	// verify that using SetDo(true) works when DO=1 (TEST #5)
33	e.SetDo(true)
34	if !e.Do() {
35		t.Errorf("DO bit should still be non-zero")
36	}
37	// verify that we can use SetDo(false) to set DO=0 (TEST #6)
38	e.SetDo(false)
39	if e.Do() {
40		t.Errorf("DO bit should be zero")
41	}
42	// verify that if we call SetDo(false) when DO=0 that it is unchanged (TEST #3)
43	e.SetDo(false)
44	if e.Do() {
45		t.Errorf("DO bit should still be zero")
46	}
47	// verify that using SetDo(true) works for DO=0 (TEST #2)
48	e.SetDo(true)
49	if !e.Do() {
50		t.Errorf("DO bit should be non-zero")
51	}
52	// verify that using SetDo() works for DO=1 (TEST #4)
53	e.SetDo()
54	if !e.Do() {
55		t.Errorf("DO bit should be non-zero")
56	}
57
58	if e.Version() != 0 {
59		t.Errorf("version should be non-zero")
60	}
61
62	e.SetVersion(42)
63	if e.Version() != 42 {
64		t.Errorf("set 42, expected %d, got %d", 42, e.Version())
65	}
66
67	e.SetExtendedRcode(42)
68	// ExtendedRcode has the last 4 bits set to 0.
69	if e.ExtendedRcode() != 42&0xFFFFFFF0 {
70		t.Errorf("set 42, expected %d, got %d", 42&0xFFFFFFF0, e.ExtendedRcode())
71	}
72
73	// This will reset the 8 upper bits of the extended rcode
74	e.SetExtendedRcode(RcodeNotAuth)
75	if e.ExtendedRcode() != 0 {
76		t.Errorf("Setting a non-extended rcode is expected to set extended rcode to 0, got: %d", e.ExtendedRcode())
77	}
78}
79
80func TestEDNS0_SUBNETUnpack(t *testing.T) {
81	for _, ip := range []net.IP{
82		net.IPv4(0xde, 0xad, 0xbe, 0xef),
83		net.ParseIP("192.0.2.1"),
84		net.ParseIP("2001:db8::68"),
85	} {
86		var s1 EDNS0_SUBNET
87		s1.Address = ip
88
89		if ip.To4() == nil {
90			s1.Family = 2
91			s1.SourceNetmask = net.IPv6len * 8
92		} else {
93			s1.Family = 1
94			s1.SourceNetmask = net.IPv4len * 8
95		}
96
97		b, err := s1.pack()
98		if err != nil {
99			t.Fatalf("failed to pack: %v", err)
100		}
101
102		var s2 EDNS0_SUBNET
103		if err := s2.unpack(b); err != nil {
104			t.Fatalf("failed to unpack: %v", err)
105		}
106
107		if !ip.Equal(s2.Address) {
108			t.Errorf("address different after unpacking; expected %s, got %s", ip, s2.Address)
109		}
110	}
111}
112
113func TestEDNS0_UL(t *testing.T) {
114	cases := []struct {
115		l  uint32
116		kl uint32
117	}{
118		{0x01234567, 0},
119		{0x76543210, 0xFEDCBA98},
120	}
121	for _, c := range cases {
122		expect := EDNS0_UL{EDNS0UL, c.l, c.kl}
123		b, err := expect.pack()
124		if err != nil {
125			t.Fatalf("failed to pack: %v", err)
126		}
127		actual := EDNS0_UL{EDNS0UL, ^uint32(0), ^uint32(0)}
128		if err := actual.unpack(b); err != nil {
129			t.Fatalf("failed to unpack: %v", err)
130		}
131		if expect != actual {
132			t.Errorf("unpacked option is different; expected %v, got %v", expect, actual)
133		}
134	}
135}
136
137func TestZ(t *testing.T) {
138	e := &OPT{}
139	e.Hdr.Name = "."
140	e.Hdr.Rrtype = TypeOPT
141	e.SetVersion(8)
142	e.SetDo()
143	if e.Z() != 0 {
144		t.Errorf("expected Z of 0, got %d", e.Z())
145	}
146	e.SetZ(5)
147	if e.Z() != 5 {
148		t.Errorf("expected Z of 5, got %d", e.Z())
149	}
150	e.SetZ(0xFFFF)
151	if e.Z() != 0x7FFF {
152		t.Errorf("expected Z of 0x7FFFF, got %d", e.Z())
153	}
154	if e.Version() != 8 {
155		t.Errorf("expected version to still be 8, got %d", e.Version())
156	}
157	if !e.Do() {
158		t.Error("expected DO to be set")
159	}
160}
161