AdGuardHome/internal/dhcpd/options_unix_test.go
Eugene Burkov fffa656758 Pull request: 4722 dhcp http panic
Merge in DNS/adguard-home from 4722-dhcp-http-panic to master

Updates #4722.

Squashed commit of the following:

commit 8a8db48c3bd4f6bb7fabe65b5b7b162f0986fc76
Merge: 39b344f9 b74b92fc
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 20:11:23 2022 +0300

    Merge branch 'master' into 4722-dhcp-http-panic

commit 39b344f97180af17ab22041e5655a27bcc99c29e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 18:33:56 2022 +0300

    dhcpd: imp code, fmt

commit a36d70d2c25791b2e657e21d6f4681b33497f0cd
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 17:38:17 2022 +0300

    dhcpd: imp names, docs

commit 600d63da7af62de5cb52fc7670ef28c9f4fe95a7
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 17:36:17 2022 +0300

    dhcpd: rename files, imp tags

commit 44f5507649db8536a07c4c21c8ad6e4a60ba3f43
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 16:40:26 2022 +0300

    dhcpd: add mock

commit cfc3cfb714705067d3aa71a7cb5df4245e091cfd
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 16:15:27 2022 +0300

    all: use ptr instead of value

commit ec526c2cf22df3470641296cfc402113c23c3f9b
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 14:57:10 2022 +0300

    all: log changes

commit 0eca09f4c72bbdc73a2334c839d7781847ba3962
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 14:50:32 2022 +0300

    dhcpd: let v4 be unconfigured

commit 59636e9ff48aea989d7bdfd216b37899b57137d2
Merge: 9238ca0a bc1503af
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 13 14:50:17 2022 +0300

    Merge branch 'master' into 4722-dhcp-http-panic

commit 9238ca0a1e190ddc344f01959f474932809f086a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Sep 7 18:28:56 2022 +0300

    dhcpd: imp conf

commit 5f801c9be96c2fa735a50373495d8c6ca2914f32
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Sep 6 16:31:13 2022 +0300

    dhcpd: hide behind iface

commit a95c2741a7e3e5bfe8775bf937a3709217b76da0
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Aug 31 16:24:02 2022 +0300

    dhcpd: separate os files
2022-09-13 23:45:35 +03:00

271 lines
6.9 KiB
Go

//go:build darwin || freebsd || linux || openbsd
package dhcpd
import (
"fmt"
"net"
"testing"
"time"
"github.com/AdguardTeam/golibs/netutil"
"github.com/AdguardTeam/golibs/testutil"
"github.com/insomniacslk/dhcp/dhcpv4"
"github.com/stretchr/testify/assert"
)
func TestParseOpt(t *testing.T) {
testCases := []struct {
name string
in string
wantCode dhcpv4.OptionCode
wantVal dhcpv4.OptionValue
wantErrMsg string
}{{
name: "hex_success",
in: "6 hex c0a80101c0a80102",
wantCode: dhcpv4.GenericOptionCode(6),
wantVal: dhcpv4.OptionGeneric{Data: []byte{
0xC0, 0xA8, 0x01, 0x01,
0xC0, 0xA8, 0x01, 0x02,
}},
wantErrMsg: "",
}, {
name: "ip_success",
in: "6 ip 1.2.3.4",
wantCode: dhcpv4.GenericOptionCode(6),
wantVal: dhcpv4.IP(net.IP{0x01, 0x02, 0x03, 0x04}),
wantErrMsg: "",
}, {
name: "ips_success",
in: "6 ips 192.168.1.1,192.168.1.2",
wantCode: dhcpv4.GenericOptionCode(6),
wantVal: dhcpv4.IPs([]net.IP{
{0xC0, 0xA8, 0x01, 0x01},
{0xC0, 0xA8, 0x01, 0x02},
}),
wantErrMsg: "",
}, {
name: "text_success",
in: "252 text http://192.168.1.1/",
wantCode: dhcpv4.GenericOptionCode(252),
wantVal: dhcpv4.String("http://192.168.1.1/"),
wantErrMsg: "",
}, {
name: "del_success",
in: "61 del",
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionClientIdentifier),
wantVal: dhcpv4.OptionGeneric{Data: nil},
wantErrMsg: "",
}, {
name: "bool_success",
in: "19 bool true",
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionIPForwarding),
wantVal: dhcpv4.OptionGeneric{Data: []byte{0x01}},
wantErrMsg: "",
}, {
name: "bool_success_false",
in: "19 bool F",
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionIPForwarding),
wantVal: dhcpv4.OptionGeneric{Data: []byte{0x00}},
wantErrMsg: "",
}, {
name: "dur_success",
in: "24 dur 2h5s",
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionPathMTUAgingTimeout),
wantVal: dhcpv4.Duration(2*time.Hour + 5*time.Second),
wantErrMsg: "",
}, {
name: "u8_success",
in: "23 u8 64",
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionDefaultIPTTL),
wantVal: dhcpv4.OptionGeneric{Data: []byte{0x40}},
wantErrMsg: "",
}, {
name: "u16_success",
in: "22 u16 1234",
wantCode: dhcpv4.GenericOptionCode(dhcpv4.OptionMaximumDatagramAssemblySize),
wantVal: dhcpv4.Uint16(1234),
wantErrMsg: "",
}, {
name: "bad_parts",
in: "6 ip",
wantCode: nil,
wantVal: nil,
wantErrMsg: `invalid option string "6 ip": bad option format`,
}, {
name: "bad_code",
in: "256 ip 1.1.1.1",
wantCode: nil,
wantVal: nil,
wantErrMsg: `invalid option string "256 ip 1.1.1.1": parsing option code: ` +
`strconv.ParseUint: parsing "256": value out of range`,
}, {
name: "bad_type",
in: "6 bad 1.1.1.1",
wantCode: nil,
wantVal: nil,
wantErrMsg: `invalid option string "6 bad 1.1.1.1": unknown option type "bad"`,
}, {
name: "hex_error",
in: "6 hex ZZZ",
wantCode: nil,
wantVal: nil,
wantErrMsg: `invalid option string "6 hex ZZZ": decoding hex: ` +
`encoding/hex: invalid byte: U+005A 'Z'`,
}, {
name: "ip_error",
in: "6 ip 1.2.3.x",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"6 ip 1.2.3.x\": bad ipv4 address \"1.2.3.x\"",
}, {
name: "ip_error_v6",
in: "6 ip ::1234",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"6 ip ::1234\": bad ipv4 address \"::1234\"",
}, {
name: "ips_error",
in: "6 ips 192.168.1.1,192.168.1.x",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"6 ips 192.168.1.1,192.168.1.x\": " +
"parsing ip at index 1: bad ipv4 address \"192.168.1.x\"",
}, {
name: "bool_error",
in: "19 bool yes",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"19 bool yes\": decoding bool: " +
"strconv.ParseBool: parsing \"yes\": invalid syntax",
}, {
name: "dur_error",
in: "24 dur 3y",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"24 dur 3y\": decoding dur: " +
"unmarshaling duration: time: unknown unit \"y\" in duration \"3y\"",
}, {
name: "u8_error",
in: "23 u8 256",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"23 u8 256\": decoding u8: " +
"strconv.ParseUint: parsing \"256\": value out of range",
}, {
name: "u16_error",
in: "23 u16 65536",
wantCode: nil,
wantVal: nil,
wantErrMsg: "invalid option string \"23 u16 65536\": decoding u16: " +
"strconv.ParseUint: parsing \"65536\": value out of range",
}}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
code, val, err := parseDHCPOption(tc.in)
testutil.AssertErrorMsg(t, tc.wantErrMsg, err)
assert.Equal(t, tc.wantCode, code)
assert.Equal(t, tc.wantVal, val)
})
}
}
func TestPrepareOptions(t *testing.T) {
oneIP, otherIP := net.IP{1, 2, 3, 4}, net.IP{5, 6, 7, 8}
testCases := []struct {
name string
wantExplicit dhcpv4.Options
opts []string
}{{
name: "all_default",
wantExplicit: nil,
opts: nil,
}, {
name: "configured_ip",
wantExplicit: dhcpv4.OptionsFromList(
dhcpv4.OptBroadcastAddress(oneIP),
),
opts: []string{
fmt.Sprintf("%d ip %s", dhcpv4.OptionBroadcastAddress, oneIP),
},
}, {
name: "configured_ips",
wantExplicit: dhcpv4.OptionsFromList(
dhcpv4.Option{
Code: dhcpv4.OptionDomainNameServer,
Value: dhcpv4.IPs{oneIP, otherIP},
},
),
opts: []string{
fmt.Sprintf("%d ips %s,%s", dhcpv4.OptionDomainNameServer, oneIP, otherIP),
},
}, {
name: "configured_bad",
wantExplicit: nil,
opts: []string{
"19 bool yes",
"24 dur 3y",
"23 u8 256",
"23 u16 65536",
"20 hex",
"23 hex abc",
"32 ips 1,2,3,4",
"28 256.256.256.256",
},
}, {
name: "configured_del",
wantExplicit: dhcpv4.OptionsFromList(
dhcpv4.OptBroadcastAddress(nil),
),
opts: []string{
"28 del",
},
}, {
name: "rewritten_del",
wantExplicit: dhcpv4.OptionsFromList(
dhcpv4.OptBroadcastAddress(netutil.IPv4bcast()),
),
opts: []string{
"28 del",
"28 ip 255.255.255.255",
},
}, {
name: "configured_and_del",
wantExplicit: dhcpv4.OptionsFromList(
dhcpv4.Option{
Code: dhcpv4.OptionGeoConf,
Value: dhcpv4.String("cba"),
},
),
opts: []string{
"123 text abc",
"123 del",
"123 text cba",
},
}}
for _, tc := range testCases {
s := &v4Server{
conf: &V4ServerConf{
// Just to avoid nil pointer dereference.
subnet: &net.IPNet{},
Options: tc.opts,
},
}
t.Run(tc.name, func(t *testing.T) {
s.prepareOptions()
assert.Equal(t, tc.wantExplicit, s.explicitOpts)
for c := range s.explicitOpts {
assert.NotContains(t, s.implicitOpts, c)
}
})
}
}