summaryrefslogtreecommitdiff
path: root/keama/tests
diff options
context:
space:
mode:
authorThomas Markwalder <tmark@isc.org>2019-11-22 13:39:45 -0500
committerThomas Markwalder <tmark@isc.org>2019-11-22 13:39:45 -0500
commit0cd94b5ef4a078097fc2bd1dc72f5e80c2cf1844 (patch)
treee4dfe9a92d676a49b18ab547d781fb3fb10c8e6a /keama/tests
parent97c155273c0df0c8518f226e2b5e338e3ad63e87 (diff)
downloadisc-dhcp-0cd94b5ef4a078097fc2bd1dc72f5e80c2cf1844.tar.gz
[#64,!35] Restored work
Restored cummulative work.
Diffstat (limited to 'keama/tests')
-rw-r--r--keama/tests/README42
-rw-r--r--keama/tests/badcasexsc.err7
-rw-r--r--keama/tests/badcasexsc.msg1
-rw-r--r--keama/tests/badclass.err12
-rw-r--r--keama/tests/badclass.msg1
-rw-r--r--keama/tests/badclass2.err12
-rw-r--r--keama/tests/badclass2.msg1
-rw-r--r--keama/tests/baddecl2array.err4
-rw-r--r--keama/tests/baddecl2array.msg1
-rw-r--r--keama/tests/baddecl2record.err4
-rw-r--r--keama/tests/baddecl2record.msg1
-rw-r--r--keama/tests/baddeclBt.err4
-rw-r--r--keama/tests/baddeclBt.msg1
-rw-r--r--keama/tests/baddefaultxsc.err7
-rw-r--r--keama/tests/baddefaultxsc.msg1
-rw-r--r--keama/tests/baddomain.notyet6
-rw-r--r--keama/tests/badduid.err4
-rw-r--r--keama/tests/badduid.msg1
-rw-r--r--keama/tests/badinclude.err3
-rw-r--r--keama/tests/badinclude.msg1
-rw-r--r--keama/tests/badoption66.err63
-rw-r--r--keama/tests/badoption66.msg1
-rw-r--r--keama/tests/badoptionD6.notyet4
-rw-r--r--keama/tests/badoptionDc4.notyet3
-rw-r--r--keama/tests/badoptionI4.err43
-rw-r--r--keama/tests/badoptionI4.msg1
-rw-r--r--keama/tests/badoptiond4.err45
-rw-r--r--keama/tests/badoptiond4.msg1
-rw-r--r--keama/tests/badstatusdir.err7
-rw-r--r--keama/tests/badstatusdir.msg1
-rw-r--r--keama/tests/badsubclass.err11
-rw-r--r--keama/tests/badsubclass.msg1
-rw-r--r--keama/tests/bintadx6.in69
-rw-r--r--keama/tests/bintadx6.out15
-rw-r--r--keama/tests/bootfilename4.in44
-rw-r--r--keama/tests/bootfilename4.out13
-rw-r--r--keama/tests/charcasedx4.in49
-rw-r--r--keama/tests/charcasedx4.out15
-rw-r--r--keama/tests/checkall.sh16
-rw-r--r--keama/tests/checkone.sh54
-rw-r--r--keama/tests/class4.in411
-rw-r--r--keama/tests/class4.out36
-rw-r--r--keama/tests/class4empty.in45
-rw-r--r--keama/tests/class4empty.out11
-rw-r--r--keama/tests/class6.in611
-rw-r--r--keama/tests/class6.out36
-rw-r--r--keama/tests/class6empty.in65
-rw-r--r--keama/tests/class6empty.out11
-rw-r--r--keama/tests/classbadmatch.err7
-rw-r--r--keama/tests/classbadmatch.msg1
-rw-r--r--keama/tests/classbadmatchif.err7
-rw-r--r--keama/tests/classbadmatchif.msg1
-rw-r--r--keama/tests/classinclass.err10
-rw-r--r--keama/tests/classinclass.msg1
-rw-r--r--keama/tests/concatdx4.in419
-rw-r--r--keama/tests/concatdx4.out48
-rw-r--r--keama/tests/concatnulldx4.in418
-rw-r--r--keama/tests/concatnulldx4.out33
-rw-r--r--keama/tests/configdata4.in426
-rw-r--r--keama/tests/configdata4.out74
-rw-r--r--keama/tests/dbtimeformat4.in46
-rw-r--r--keama/tests/dbtimeformat4.out10
-rw-r--r--keama/tests/dbtimeformat6.in66
-rw-r--r--keama/tests/dbtimeformat6.out10
-rw-r--r--keama/tests/ddnsupdstyle6.in612
-rw-r--r--keama/tests/ddnsupdstyle6.out29
-rw-r--r--keama/tests/defaultexpr6.in610
-rw-r--r--keama/tests/defaultexpr6.out25
-rw-r--r--keama/tests/denyunknown6.in615
-rw-r--r--keama/tests/denyunknown6.out32
-rw-r--r--keama/tests/docsis4.dir11
-rw-r--r--keama/tests/docsis6.dir27
-rw-r--r--keama/tests/duid2.err7
-rw-r--r--keama/tests/duid2.msg1
-rw-r--r--keama/tests/duiden6.in64
-rw-r--r--keama/tests/duiden6.out11
-rw-r--r--keama/tests/duidennoid.err5
-rw-r--r--keama/tests/duidennoid.msg1
-rw-r--r--keama/tests/duidennonum.err4
-rw-r--r--keama/tests/duidennonum.msg1
-rw-r--r--keama/tests/duidll6.in65
-rw-r--r--keama/tests/duidll6.out9
-rw-r--r--keama/tests/duidllbadtype.err4
-rw-r--r--keama/tests/duidllbadtype.msg1
-rw-r--r--keama/tests/duidllhw6.in66
-rw-r--r--keama/tests/duidllhw6.out11
-rw-r--r--keama/tests/duidllnohw.err4
-rw-r--r--keama/tests/duidllnohw.msg1
-rw-r--r--keama/tests/duidllt6.in65
-rw-r--r--keama/tests/duidllt6.out9
-rw-r--r--keama/tests/duidlltbadtype.err4
-rw-r--r--keama/tests/duidlltbadtype.msg1
-rw-r--r--keama/tests/duidlltnohw.err4
-rw-r--r--keama/tests/duidlltnohw.msg1
-rw-r--r--keama/tests/duidlltnotime.err4
-rw-r--r--keama/tests/duidlltnotime.msg1
-rw-r--r--keama/tests/duidlltthw4.err44
-rw-r--r--keama/tests/duidlltthw4.msg1
-rw-r--r--keama/tests/duidlltthw6.in64
-rw-r--r--keama/tests/duidlltthw6.out12
-rw-r--r--keama/tests/duidnoid.err4
-rw-r--r--keama/tests/duidnoid.msg1
-rw-r--r--keama/tests/enableupdates6.in68
-rw-r--r--keama/tests/enableupdates6.out20
-rw-r--r--keama/tests/encodedx6.in69
-rw-r--r--keama/tests/encodedx6.out15
-rw-r--r--keama/tests/env3
-rw-r--r--keama/tests/escapestring4.in46
-rw-r--r--keama/tests/escapestring4.out23
-rw-r--r--keama/tests/execstatement4.in47
-rw-r--r--keama/tests/execstatement4.out11
-rw-r--r--keama/tests/execstatement6.in67
-rw-r--r--keama/tests/execstatement6.out11
-rw-r--r--keama/tests/existsbx4.in415
-rw-r--r--keama/tests/existsbx4.out48
-rw-r--r--keama/tests/filename4.in410
-rw-r--r--keama/tests/filename4.out17
-rw-r--r--keama/tests/filenamedx4.notyet20
-rw-r--r--keama/tests/fixedaddressinroot4.err44
-rw-r--r--keama/tests/fixedaddressinroot4.msg1
-rw-r--r--keama/tests/fixedaddressinroot6.err64
-rw-r--r--keama/tests/fixedaddressinroot6.msg1
-rw-r--r--keama/tests/fixedprefixinroot.err64
-rw-r--r--keama/tests/fixedprefixinroot.msg1
-rw-r--r--keama/tests/fqdncompressed.err67
-rw-r--r--keama/tests/fqdncompressed.msg1
-rw-r--r--keama/tests/gethostdx4.notyet13
-rw-r--r--keama/tests/global4.in410
-rw-r--r--keama/tests/global4.out28
-rw-r--r--keama/tests/global6.in610
-rw-r--r--keama/tests/global6.out26
-rw-r--r--keama/tests/groupclass4.in432
-rw-r--r--keama/tests/groupclass4.out102
-rw-r--r--keama/tests/groupclass6.in635
-rw-r--r--keama/tests/groupclass6.out123
-rw-r--r--keama/tests/groupgroup4.in445
-rw-r--r--keama/tests/groupgroup4.out138
-rw-r--r--keama/tests/grouphost4.inn35
-rw-r--r--keama/tests/grouphost4.out78
-rw-r--r--keama/tests/groupinclass.err10
-rw-r--r--keama/tests/groupinclass.msg1
-rw-r--r--keama/tests/groupsubnet4.in424
-rw-r--r--keama/tests/groupsubnet4.out38
-rw-r--r--keama/tests/groupsubnet6.in624
-rw-r--r--keama/tests/groupsubnet6.out44
-rw-r--r--keama/tests/groupsubnetif.err419
-rw-r--r--keama/tests/groupsubnetif.msg1
-rw-r--r--keama/tests/hardware2dx4.in413
-rw-r--r--keama/tests/hardware2dx4.out25
-rw-r--r--keama/tests/hardwaredx4.in416
-rw-r--r--keama/tests/hardwaredx4.out55
-rw-r--r--keama/tests/hardwareinroot.err5
-rw-r--r--keama/tests/hardwareinroot.msg1
-rw-r--r--keama/tests/host6.notyet20
-rw-r--r--keama/tests/hostidentifier4.inl30
-rw-r--r--keama/tests/hostidentifier4.outl78
-rw-r--r--keama/tests/hostinclass.err10
-rw-r--r--keama/tests/hostinclass.msg1
-rw-r--r--keama/tests/hostinhost.err11
-rw-r--r--keama/tests/hostinhost.msg1
-rw-r--r--keama/tests/hostname4.in418
-rw-r--r--keama/tests/hostname4.out37
-rw-r--r--keama/tests/hostnum.errF7
-rw-r--r--keama/tests/hostnum.msg1
-rw-r--r--keama/tests/hostuid4.inn29
-rw-r--r--keama/tests/hostuid4.out62
-rw-r--r--keama/tests/ifxsc4.in417
-rw-r--r--keama/tests/ifxsc4.out79
-rw-r--r--keama/tests/ipaddr6.in63
-rw-r--r--keama/tests/ipaddr6.out14
-rw-r--r--keama/tests/ipaddrhost4.in48
-rw-r--r--keama/tests/ipaddrhost4.out24
-rw-r--r--keama/tests/ipaddrs4.notyet411
-rw-r--r--keama/tests/lifetime4.ind5
-rw-r--r--keama/tests/lifetime4.out8
-rw-r--r--keama/tests/lifetime6.inD5
-rw-r--r--keama/tests/lifetime6.out8
-rw-r--r--keama/tests/lifetimedef4.ind1
-rw-r--r--keama/tests/lifetimedef4.out11
-rw-r--r--keama/tests/lifetimedef6.inD1
-rw-r--r--keama/tests/lifetimedef6.out11
-rw-r--r--keama/tests/listarray.err7
-rw-r--r--keama/tests/listarray.msg1
-rw-r--r--keama/tests/minimal4.in44
-rw-r--r--keama/tests/minimal4.out7
-rw-r--r--keama/tests/minimal6.in64
-rw-r--r--keama/tests/minimal6.out7
-rw-r--r--keama/tests/mixedarray.err7
-rw-r--r--keama/tests/mixedarray.msg1
-rw-r--r--keama/tests/nestarray.err7
-rw-r--r--keama/tests/nestarray.msg1
-rw-r--r--keama/tests/noauth4.in47
-rw-r--r--keama/tests/noauth4.out15
-rw-r--r--keama/tests/noauth6.in66
-rw-r--r--keama/tests/noauth6.out15
-rw-r--r--keama/tests/noclass.err7
-rw-r--r--keama/tests/noclass.msg1
-rw-r--r--keama/tests/noinclude.err3
-rw-r--r--keama/tests/noinclude.msg1
-rw-r--r--keama/tests/nosubclass.err11
-rw-r--r--keama/tests/nosubclass.msg1
-rw-r--r--keama/tests/nosuperclass.err11
-rw-r--r--keama/tests/nosuperclass.msg1
-rw-r--r--keama/tests/notbx4.in412
-rw-r--r--keama/tests/notbx4.out30
-rw-r--r--keama/tests/notnotbx4.in415
-rw-r--r--keama/tests/notnotbx4.out21
-rw-r--r--keama/tests/nxdomainnx6.in612
-rw-r--r--keama/tests/nxdomainnx6.out28
-rw-r--r--keama/tests/onxsc4.in412
-rw-r--r--keama/tests/onxsc4.out34
-rw-r--r--keama/tests/optdatagrouppool4.in418
-rw-r--r--keama/tests/optdatagrouppool4.out23
-rw-r--r--keama/tests/optiondata4.in448
-rw-r--r--keama/tests/optiondata4.out173
-rw-r--r--keama/tests/optiondata6.in649
-rw-r--r--keama/tests/optiondata6.out178
-rw-r--r--keama/tests/optiondatapool4.in412
-rw-r--r--keama/tests/optiondatapool4.out31
-rw-r--r--keama/tests/optiondatapool6.in613
-rw-r--r--keama/tests/optiondatapool6.out32
-rw-r--r--keama/tests/optiondecl4.in427
-rw-r--r--keama/tests/optiondecl4.out143
-rw-r--r--keama/tests/optiondecl6.in627
-rw-r--r--keama/tests/optiondecl6.out137
-rw-r--r--keama/tests/optiondeclBat4.in46
-rw-r--r--keama/tests/optiondeclBat4.out18
-rw-r--r--keama/tests/optionencap4.in47
-rw-r--r--keama/tests/optionencap4.out15
-rw-r--r--keama/tests/optionencap6.in67
-rw-r--r--keama/tests/optionencap6.out15
-rw-r--r--keama/tests/optionexpr4.in416
-rw-r--r--keama/tests/optionexpr4.out81
-rw-r--r--keama/tests/optionspace4.in415
-rw-r--r--keama/tests/optionspace4.out34
-rw-r--r--keama/tests/optionspace6.in615
-rw-r--r--keama/tests/optionspace6.out34
-rw-r--r--keama/tests/optionvendor4.in48
-rw-r--r--keama/tests/optionvendor4.out28
-rw-r--r--keama/tests/optionvendor6.in68
-rw-r--r--keama/tests/optionvendor6.out28
-rw-r--r--keama/tests/orphan4.inn10
-rw-r--r--keama/tests/orphan4.out30
-rw-r--r--keama/tests/orphan6.inN10
-rw-r--r--keama/tests/orphan6.out28
-rw-r--r--keama/tests/packetdx4.notyet20
-rw-r--r--keama/tests/permitauth4.in415
-rw-r--r--keama/tests/permitauth4.out33
-rw-r--r--keama/tests/permitauth6.in615
-rw-r--r--keama/tests/permitauth6.out33
-rw-r--r--keama/tests/permitknown4.in415
-rw-r--r--keama/tests/permitknown4.out26
-rw-r--r--keama/tests/pickdx6.in615
-rw-r--r--keama/tests/pickdx6.out21
-rw-r--r--keama/tests/pool4.in411
-rw-r--r--keama/tests/pool4.out31
-rw-r--r--keama/tests/pool42.in415
-rw-r--r--keama/tests/pool42.out49
-rw-r--r--keama/tests/pool6.in611
-rw-r--r--keama/tests/pool6.out31
-rw-r--r--keama/tests/pool6in4.err413
-rw-r--r--keama/tests/pool6in4.msg1
-rw-r--r--keama/tests/poolinroot4.err47
-rw-r--r--keama/tests/poolinroot4.msg1
-rw-r--r--keama/tests/poolinroot6.err67
-rw-r--r--keama/tests/poolinroot6.msg1
-rw-r--r--keama/tests/preferred6.in614
-rw-r--r--keama/tests/preferred6.out30
-rw-r--r--keama/tests/prefix0.err69
-rw-r--r--keama/tests/prefix0.msg1
-rw-r--r--keama/tests/prefix128.err69
-rw-r--r--keama/tests/prefix128.msg1
-rw-r--r--keama/tests/prefix6.in69
-rw-r--r--keama/tests/prefix6.out32
-rw-r--r--keama/tests/prefix62.in610
-rw-r--r--keama/tests/prefix62.out36
-rw-r--r--keama/tests/prefixinroot6.err64
-rw-r--r--keama/tests/prefixinroot6.msg1
-rw-r--r--keama/tests/qualifyingsuffix4.in49
-rw-r--r--keama/tests/qualifyingsuffix4.out17
-rw-r--r--keama/tests/qualifyingsuffix6.in68
-rw-r--r--keama/tests/qualifyingsuffix6.out17
-rw-r--r--keama/tests/range4.in49
-rw-r--r--keama/tests/range4.out30
-rw-r--r--keama/tests/range6.in611
-rw-r--r--keama/tests/range6.out37
-rw-r--r--keama/tests/range6in4.err45
-rw-r--r--keama/tests/range6in4.msg1
-rw-r--r--keama/tests/rangeinroot4.err44
-rw-r--r--keama/tests/rangeinroot4.msg1
-rw-r--r--keama/tests/rangeinroot6.err65
-rw-r--r--keama/tests/rangeinroot6.msg1
-rw-r--r--keama/tests/reversedx6.in69
-rw-r--r--keama/tests/reversedx6.out15
-rw-r--r--keama/tests/runall.sh15
-rw-r--r--keama/tests/runone.sh119
-rw-r--r--keama/tests/samples/example.conf111
-rw-r--r--keama/tests/samples/example.conf.orig104
-rw-r--r--keama/tests/samples/example.json223
-rw-r--r--keama/tests/samples/runall.sh11
-rw-r--r--keama/tests/samples/runone.sh39
-rw-r--r--keama/tests/samples/simple.conf33
-rw-r--r--keama/tests/samples/simple.json53
-rw-r--r--keama/tests/samples/test-a6.conf75
-rw-r--r--keama/tests/samples/test-a6.conf.orig67
-rw-r--r--keama/tests/samples/test-a6.json144
-rw-r--r--keama/tests/samples/vmnet8.conf43
-rw-r--r--keama/tests/samples/vmnet8.conf.orig43
-rw-r--r--keama/tests/samples/vmnet8.json105
-rw-r--r--keama/tests/share0.err6
-rw-r--r--keama/tests/share0.msg1
-rw-r--r--keama/tests/share2if.err7
-rw-r--r--keama/tests/share2if.msg1
-rw-r--r--keama/tests/shareempty.err6
-rw-r--r--keama/tests/shareempty.msg1
-rw-r--r--keama/tests/shareinclass.err11
-rw-r--r--keama/tests/shareinclass.msg1
-rw-r--r--keama/tests/shareinhost.err11
-rw-r--r--keama/tests/shareinhost.msg1
-rw-r--r--keama/tests/shareinshare.err10
-rw-r--r--keama/tests/shareinshare.msg1
-rw-r--r--keama/tests/shareinsubnet4.err410
-rw-r--r--keama/tests/shareinsubnet4.msg1
-rw-r--r--keama/tests/shareinsubnet6.err610
-rw-r--r--keama/tests/shareinsubnet6.msg1
-rw-r--r--keama/tests/sharenoname.err6
-rw-r--r--keama/tests/sharenoname.msg1
-rw-r--r--keama/tests/shareone4.in422
-rw-r--r--keama/tests/shareone4.out44
-rw-r--r--keama/tests/shareone6.in619
-rw-r--r--keama/tests/shareone6.out37
-rw-r--r--keama/tests/sharepools4.in427
-rw-r--r--keama/tests/sharepools4.out63
-rw-r--r--keama/tests/sharetwo4.in429
-rw-r--r--keama/tests/sharetwo4.out64
-rw-r--r--keama/tests/sharetwo6.in624
-rw-r--r--keama/tests/sharetwo6.out56
-rw-r--r--keama/tests/sname4.notyet20
-rw-r--r--keama/tests/spawning6.in611
-rw-r--r--keama/tests/spawning6.out37
-rw-r--r--keama/tests/subclass4.in423
-rw-r--r--keama/tests/subclass4.out84
-rw-r--r--keama/tests/subclass6.in623
-rw-r--r--keama/tests/subclass6.out89
-rw-r--r--keama/tests/subclassbinsel4.in416
-rw-r--r--keama/tests/subclassbinsel4.out61
-rw-r--r--keama/tests/subclassbinsel6.in625
-rw-r--r--keama/tests/subclassbinsel6.out88
-rw-r--r--keama/tests/subclassguard4.in424
-rw-r--r--keama/tests/subclassguard4.out79
-rw-r--r--keama/tests/subclassguard6.in624
-rw-r--r--keama/tests/subclassguard6.out84
-rw-r--r--keama/tests/subnet4.in416
-rw-r--r--keama/tests/subnet4.out33
-rw-r--r--keama/tests/subnet42if.err48
-rw-r--r--keama/tests/subnet42if.msg1
-rw-r--r--keama/tests/subnet4auth.in418
-rw-r--r--keama/tests/subnet4auth.out35
-rw-r--r--keama/tests/subnet4badmask.err47
-rw-r--r--keama/tests/subnet4badmask.msg1
-rw-r--r--keama/tests/subnet4inclass.err410
-rw-r--r--keama/tests/subnet4inclass.msg1
-rw-r--r--keama/tests/subnet4inhost.err411
-rw-r--r--keama/tests/subnet4inhost.msg1
-rw-r--r--keama/tests/subnet4nomask.err47
-rw-r--r--keama/tests/subnet4nomask.msg1
-rw-r--r--keama/tests/subnet6.in618
-rw-r--r--keama/tests/subnet6.out39
-rw-r--r--keama/tests/subnet62if.err68
-rw-r--r--keama/tests/subnet62if.msg1
-rw-r--r--keama/tests/subnet6auth.in621
-rw-r--r--keama/tests/subnet6auth.out44
-rw-r--r--keama/tests/subnet6inclass.err610
-rw-r--r--keama/tests/subnet6inclass.msg1
-rw-r--r--keama/tests/subnet6inhost.err611
-rw-r--r--keama/tests/subnet6inhost.msg1
-rw-r--r--keama/tests/subnet6multi.in619
-rw-r--r--keama/tests/subnet6multi.out49
-rw-r--r--keama/tests/subnet6nolen.err67
-rw-r--r--keama/tests/subnet6nolen.msg1
-rw-r--r--keama/tests/subnet6noslash.err67
-rw-r--r--keama/tests/subnet6noslash.msg1
-rw-r--r--keama/tests/subnet6one.in618
-rw-r--r--keama/tests/subnet6one.out45
-rw-r--r--keama/tests/subnetinsubnet4.err410
-rw-r--r--keama/tests/subnetinsubnet4.msg1
-rw-r--r--keama/tests/subnetinsubnet6.err610
-rw-r--r--keama/tests/subnetinsubnet6.msg1
-rw-r--r--keama/tests/substringdx4.in421
-rw-r--r--keama/tests/substringdx4.out49
-rw-r--r--keama/tests/suffixdx4.in426
-rw-r--r--keama/tests/suffixdx4.out74
-rw-r--r--keama/tests/switchxsc4.in418
-rw-r--r--keama/tests/switchxsc4.out79
-rw-r--r--keama/tests/switchxsc6.in618
-rw-r--r--keama/tests/switchxsc6.out82
-rw-r--r--keama/tests/tautology.err9
-rw-r--r--keama/tests/tautology.msg1
-rw-r--r--keama/tests/tautologyhexa.err9
-rw-r--r--keama/tests/tautologyhexa.msg1
-rw-r--r--keama/tests/tautologysub.err9
-rw-r--r--keama/tests/tautologysub.msg1
-rw-r--r--keama/tests/temporary6.in610
-rw-r--r--keama/tests/temporary6.out33
-rw-r--r--keama/tests/textarray.err7
-rw-r--r--keama/tests/textarray.msg1
-rw-r--r--keama/tests/unknownoption.err4
-rw-r--r--keama/tests/unknownoption.msg1
-rw-r--r--keama/tests/unknownspace.err4
-rw-r--r--keama/tests/unknownspace.msg1
-rw-r--r--keama/tests/userclass.err6
-rw-r--r--keama/tests/userclass.msg1
-rw-r--r--keama/tests/vendorclass.err6
-rw-r--r--keama/tests/vendorclass.msg1
-rw-r--r--keama/tests/vendorspace4.in411
-rw-r--r--keama/tests/vendorspace4.out41
-rw-r--r--keama/tests/zone4.in424
-rw-r--r--keama/tests/zone4.out47
418 files changed, 8430 insertions, 0 deletions
diff --git a/keama/tests/README b/keama/tests/README
new file mode 100644
index 00000000..69686155
--- /dev/null
+++ b/keama/tests/README
@@ -0,0 +1,42 @@
+Tests are dividing on error vs working, and DHCPv4 vs DHCPv6.
+
+Names of files about test xyz have xyz as body and an extension.
+
+Extensions:
+ - .err4 = source for error test in DHCPv4
+ - .errF = source for error test in DHCPv4 with -r fatal
+ - .errP = source for error test in DHCPv4 with -r pass
+ - .err6 = source for error test in DHCPv6
+ - .err = source for error test in DHCPv4 and DHCPv6
+ - .msg = resultat (first line of standard error) for error test
+ - .in4 = source for working test in DHCPv4
+ - .in6 = source for working test in DHCPv6
+ - .ind = source for working test in DHCPv4 with -D
+ - .inD = source for working test in DHCPv6 with -D
+ - .inn = source for working test in DHCPv4 with -N
+ - .inN = source for working test in DHCPv6 with -N
+ - .inl = source for working test in DHCPv4 with -l $HOOK
+ - .inL = source for working test in DHCPv6 with -l $HOOK
+ - .outl = resultat for working test with default hook library path
+ - .outL = resultat for working test with default hook library path
+ - .out = resultat for working test
+There is no working test in both DHCPv4 and DHCPv6.
+The body of the name of a working test must include 4 or 6 so
+the .out can be submitted to kea-dhcp4 or kea-dhcp6
+
+runone.sh xyz.ext
+ -> run the xyz test
+runall.sh
+ -> run all tests
+
+Check output syntax with kea-dhcp4 and kea-dhcp6:
+ - Set KEA4 and KEA6 environment variables to kea-dhcp4 and kea-dhcp6
+ - Set HOOK to a place to find hooks (currently libdhcp_flex_id.so),
+ please use the directory name with a trailing /
+ - The en0 interface is supposed to exist (or replace "en0" in all files)
+ - Note that runall.sh must be run before checkall.sh
+
+checkone.sh xyz.out
+ -> check the syntax of xyz.out
+checkall.sh
+ -> check the syntax of all .out files
diff --git a/keama/tests/badcasexsc.err b/keama/tests/badcasexsc.err
new file mode 100644
index 00000000..9cfdd87c
--- /dev/null
+++ b/keama/tests/badcasexsc.err
@@ -0,0 +1,7 @@
+# bad case executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# a raw default statement
+case "foo": break;
diff --git a/keama/tests/badcasexsc.msg b/keama/tests/badcasexsc.msg
new file mode 100644
index 00000000..636bb31a
--- /dev/null
+++ b/keama/tests/badcasexsc.msg
@@ -0,0 +1 @@
+badcasexsc.err line 7: case statement in inappropriate scope.
diff --git a/keama/tests/badclass.err b/keama/tests/badclass.err
new file mode 100644
index 00000000..8dc59c05
--- /dev/null
+++ b/keama/tests/badclass.err
@@ -0,0 +1,12 @@
+# bad (double match-if) class declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+
+# class declaration
+class "foobar" {
+ match if option mysystem = "version1";
+ match if option mysystem = "version2";
+ option myversion 1;
+}
diff --git a/keama/tests/badclass.msg b/keama/tests/badclass.msg
new file mode 100644
index 00000000..69a603ab
--- /dev/null
+++ b/keama/tests/badclass.msg
@@ -0,0 +1 @@
+badclass.err line 10: A class may only have one 'match if' clause.
diff --git a/keama/tests/badclass2.err b/keama/tests/badclass2.err
new file mode 100644
index 00000000..551a1729
--- /dev/null
+++ b/keama/tests/badclass2.err
@@ -0,0 +1,12 @@
+# bad (2 match) class declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ match option mysystem;
+ match option myversion;
+ option myversion 1;
+}
diff --git a/keama/tests/badclass2.msg b/keama/tests/badclass2.msg
new file mode 100644
index 00000000..3afd2b3b
--- /dev/null
+++ b/keama/tests/badclass2.msg
@@ -0,0 +1 @@
+badclass2.err line 10: can't override existing submatch/spawn
diff --git a/keama/tests/baddecl2array.err b/keama/tests/baddecl2array.err
new file mode 100644
index 00000000..80701141
--- /dev/null
+++ b/keama/tests/baddecl2array.err
@@ -0,0 +1,4 @@
+# bad 2a (array in array) option declaration
+
+option space foobar;
+option foobar.fmt-Bat code 1 = array of array of unsigned integer 8;
diff --git a/keama/tests/baddecl2array.msg b/keama/tests/baddecl2array.msg
new file mode 100644
index 00000000..e7ad089e
--- /dev/null
+++ b/keama/tests/baddecl2array.msg
@@ -0,0 +1 @@
+baddecl2array.err line 4: no nested arrays.
diff --git a/keama/tests/baddecl2record.err b/keama/tests/baddecl2record.err
new file mode 100644
index 00000000..d237b636
--- /dev/null
+++ b/keama/tests/baddecl2record.err
@@ -0,0 +1,4 @@
+# bad 2r (record in record) option declaration
+
+option space foobar;
+option foobar.fmt-Bat code 1 = { unsigned integer 8, { text } };
diff --git a/keama/tests/baddecl2record.msg b/keama/tests/baddecl2record.msg
new file mode 100644
index 00000000..4dfb2082
--- /dev/null
+++ b/keama/tests/baddecl2record.msg
@@ -0,0 +1 @@
+baddecl2record.err line 4: unknown data type {
diff --git a/keama/tests/baddeclBt.err b/keama/tests/baddeclBt.err
new file mode 100644
index 00000000..921521f2
--- /dev/null
+++ b/keama/tests/baddeclBt.err
@@ -0,0 +1,4 @@
+# bad Bt (not in record) option declaration
+
+option space foobar;
+option foobar.fmt-Bat code 1 = unsigned integer 8, text;
diff --git a/keama/tests/baddeclBt.msg b/keama/tests/baddeclBt.msg
new file mode 100644
index 00000000..49c63a58
--- /dev/null
+++ b/keama/tests/baddeclBt.msg
@@ -0,0 +1 @@
+baddeclBt.err line 4: semicolon expected.
diff --git a/keama/tests/baddefaultxsc.err b/keama/tests/baddefaultxsc.err
new file mode 100644
index 00000000..69157dd4
--- /dev/null
+++ b/keama/tests/baddefaultxsc.err
@@ -0,0 +1,7 @@
+# bad default executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# a raw default statement
+default: break;
diff --git a/keama/tests/baddefaultxsc.msg b/keama/tests/baddefaultxsc.msg
new file mode 100644
index 00000000..7780a1bb
--- /dev/null
+++ b/keama/tests/baddefaultxsc.msg
@@ -0,0 +1 @@
+baddefaultxsc.err line 7: switch default statement in inappropriate scope.
diff --git a/keama/tests/baddomain.notyet b/keama/tests/baddomain.notyet
new file mode 100644
index 00000000..a38f21c9
--- /dev/null
+++ b/keama/tests/baddomain.notyet
@@ -0,0 +1,6 @@
+# bad domain (label too long) option data
+
+option space foobar;
+option foobar.fmt-d code 1 = domain-name;
+option foobar.fmt-d
+ this-label-is-very-very-very-very-very-very-long-so-it-is-too-long.us;
diff --git a/keama/tests/badduid.err b/keama/tests/badduid.err
new file mode 100644
index 00000000..c3acab31
--- /dev/null
+++ b/keama/tests/badduid.err
@@ -0,0 +1,4 @@
+# bad (no type) server duid config
+
+# server duid declaration
+server-duid "enterprise-specific-identifier-1234";
diff --git a/keama/tests/badduid.msg b/keama/tests/badduid.msg
new file mode 100644
index 00000000..ebcaade4
--- /dev/null
+++ b/keama/tests/badduid.msg
@@ -0,0 +1 @@
+badduid.err line 4: DUID type of LLT, EN, or LL expected
diff --git a/keama/tests/badinclude.err b/keama/tests/badinclude.err
new file mode 100644
index 00000000..7ab310ff
--- /dev/null
+++ b/keama/tests/badinclude.err
@@ -0,0 +1,3 @@
+# bad include config
+
+include 192.168.0.1;
diff --git a/keama/tests/badinclude.msg b/keama/tests/badinclude.msg
new file mode 100644
index 00000000..e7ebf997
--- /dev/null
+++ b/keama/tests/badinclude.msg
@@ -0,0 +1 @@
+badinclude.err line 3: filename string expected.
diff --git a/keama/tests/badoption66.err6 b/keama/tests/badoption66.err6
new file mode 100644
index 00000000..a972d2f2
--- /dev/null
+++ b/keama/tests/badoption66.err6
@@ -0,0 +1,3 @@
+# bad '6' (Ipv6 address) option data
+
+option dhcp6.unicast "2001::1";
diff --git a/keama/tests/badoption66.msg b/keama/tests/badoption66.msg
new file mode 100644
index 00000000..227ce94d
--- /dev/null
+++ b/keama/tests/badoption66.msg
@@ -0,0 +1 @@
+badoption66.err6 line 3: Invalid IPv6 address.
diff --git a/keama/tests/badoptionD6.notyet b/keama/tests/badoptionD6.notyet
new file mode 100644
index 00000000..daf9541c
--- /dev/null
+++ b/keama/tests/badoptionD6.notyet
@@ -0,0 +1,4 @@
+# bad 'D' (domain-list) option data
+
+option dhcp6.domain-search example.com;
+
diff --git a/keama/tests/badoptionDc4.notyet b/keama/tests/badoptionDc4.notyet
new file mode 100644
index 00000000..f56fb46a
--- /dev/null
+++ b/keama/tests/badoptionDc4.notyet
@@ -0,0 +1,3 @@
+# bad 'Dc' (domain-list compressed) option data
+
+option domain-search example.com;
diff --git a/keama/tests/badoptionI4.err4 b/keama/tests/badoptionI4.err4
new file mode 100644
index 00000000..b0f6331d
--- /dev/null
+++ b/keama/tests/badoptionI4.err4
@@ -0,0 +1,3 @@
+# bad 'I' (IPv4 address) option data
+
+option swap-server "10.5.5.1";
diff --git a/keama/tests/badoptionI4.msg b/keama/tests/badoptionI4.msg
new file mode 100644
index 00000000..6609975d
--- /dev/null
+++ b/keama/tests/badoptionI4.msg
@@ -0,0 +1 @@
+badoptionI4.err4 line 3: 10.5.5.1 (262): expecting IP address or hostname
diff --git a/keama/tests/badoptiond4.err4 b/keama/tests/badoptiond4.err4
new file mode 100644
index 00000000..005c26cd
--- /dev/null
+++ b/keama/tests/badoptiond4.err4
@@ -0,0 +1,5 @@
+# bad d (domain-name) option data
+
+option space foobar;
+option foobar.fmt-d code 13 = domain-name;
+option foobar.fmt-d "www.example.com";
diff --git a/keama/tests/badoptiond4.msg b/keama/tests/badoptiond4.msg
new file mode 100644
index 00000000..e1f833e7
--- /dev/null
+++ b/keama/tests/badoptiond4.msg
@@ -0,0 +1 @@
+badoptiond4.err4 line 5: not a valid domain name.
diff --git a/keama/tests/badstatusdir.err b/keama/tests/badstatusdir.err
new file mode 100644
index 00000000..aab8fd56
--- /dev/null
+++ b/keama/tests/badstatusdir.err
@@ -0,0 +1,7 @@
+# Bad status directive
+
+option space foobar;
+option foobar.opt1 code 1 = text;
+
+# unknown/unknown does not make sense
+% option foobar.opt1 unknown unknown;
diff --git a/keama/tests/badstatusdir.msg b/keama/tests/badstatusdir.msg
new file mode 100644
index 00000000..d020cee4
--- /dev/null
+++ b/keama/tests/badstatusdir.msg
@@ -0,0 +1 @@
+badstatusdir.err line 7: illicit combination: option foobar.opt1 code 1 is known by nobody
diff --git a/keama/tests/badsubclass.err b/keama/tests/badsubclass.err
new file mode 100644
index 00000000..38c817b7
--- /dev/null
+++ b/keama/tests/badsubclass.err
@@ -0,0 +1,11 @@
+# bad (selector type) subclass declaration config
+
+# superclass declaration
+class "foobar" {
+ match substring(option vendor-class-identifier, 0, 3);
+}
+
+# subclass declaration
+subclass "foobar" true {
+ default-lease-time 1800;
+}
diff --git a/keama/tests/badsubclass.msg b/keama/tests/badsubclass.msg
new file mode 100644
index 00000000..a0a85028
--- /dev/null
+++ b/keama/tests/badsubclass.msg
@@ -0,0 +1 @@
+badsubclass.err line 9: Expecting string or hex list.
diff --git a/keama/tests/bintadx6.in6 b/keama/tests/bintadx6.in6
new file mode 100644
index 00000000..dc0cede7
--- /dev/null
+++ b/keama/tests/bintadx6.in6
@@ -0,0 +1,9 @@
+# binary-to-ascii data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# reduce literals
+class "literal" {
+ match if option dhcp6.client-data = binary-to-ascii(16, 8, "-", "\007foo");
+}
diff --git a/keama/tests/bintadx6.out b/keama/tests/bintadx6.out
new file mode 100644
index 00000000..999e3602
--- /dev/null
+++ b/keama/tests/bintadx6.out
@@ -0,0 +1,15 @@
+{
+ # binary-to-ascii data expression
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # reduce literals
+ {
+ "name": "literal",
+ /// from: match if (option dhcp6.client-data) = (binary-to-ascii(16, 8, '-', 'foo'))
+ "test": "option[45].hex == '7-66-6f-6f'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/bootfilename4.in4 b/keama/tests/bootfilename4.in4
new file mode 100644
index 00000000..5b6daeba
--- /dev/null
+++ b/keama/tests/bootfilename4.in4
@@ -0,0 +1,4 @@
+# Gitlab #22 dhcp4 option 67 wrong name
+
+option bootfile-name "boot.pxe";
+
diff --git a/keama/tests/bootfilename4.out b/keama/tests/bootfilename4.out
new file mode 100644
index 00000000..a08cb625
--- /dev/null
+++ b/keama/tests/bootfilename4.out
@@ -0,0 +1,13 @@
+{
+ # Gitlab #22 dhcp4 option 67 wrong name
+ "Dhcp4": {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "boot-file-name",
+ "code": 67,
+ "data": "boot.pxe"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/charcasedx4.in4 b/keama/tests/charcasedx4.in4
new file mode 100644
index 00000000..dd9ba03e
--- /dev/null
+++ b/keama/tests/charcasedx4.in4
@@ -0,0 +1,9 @@
+# lcase/ucase data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# reduce literals
+class "literal" {
+ match if option host-name = concat(ucase("www."), "example.", lcase("COM"));
+}
diff --git a/keama/tests/charcasedx4.out b/keama/tests/charcasedx4.out
new file mode 100644
index 00000000..fcdc20d1
--- /dev/null
+++ b/keama/tests/charcasedx4.out
@@ -0,0 +1,15 @@
+{
+ # lcase/ucase data expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # reduce literals
+ {
+ "name": "literal",
+ /// from: match if (option dhcp.host-name) = (concat(uppercase('www.'), concat('example.', lowercase('COM'))))
+ "test": "option[12].hex == 'WWW.example.com'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/checkall.sh b/keama/tests/checkall.sh
new file mode 100644
index 00000000..edeffdcb
--- /dev/null
+++ b/keama/tests/checkall.sh
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+#set -x
+
+cd "$(dirname "$0")"
+
+log=/tmp/log
+rm $log 2> /dev/null
+
+for t in *.out
+do
+ /bin/sh checkone.sh $t
+ if [ $? -ne 0 ]; then
+ echo `basename $t` >> $log
+ fi
+done
diff --git a/keama/tests/checkone.sh b/keama/tests/checkone.sh
new file mode 100644
index 00000000..cbd5d9fd
--- /dev/null
+++ b/keama/tests/checkone.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+#set -x
+
+if [ $# -ne 1 ]; then
+ echo "usage: $0 test-name" >&2
+ exit 1
+fi
+
+if [ x$KEA4 = x ]; then
+ echo "KEA4 is not set" >&2
+fi
+if [ x$KEA6 = x ]; then
+ echo "KEA6 is not set" >&2
+fi
+
+file=$1
+
+cd "$(dirname "$0")"
+
+isout=$(expr $file : ".*\.out")
+if [ $isout -eq 0 ]; then
+ full=$file.out
+else
+ full=$file
+fi
+if [ ! -f $full ]; then
+ echo "can't find $file" >&2
+ exit 1
+fi
+
+is4=$(expr $file : ".*4")
+is6=$(expr $file : ".*6")
+if [ \( $is4 -eq 0 \) -a \( $is6 -eq 0 \) ]; then
+ echo "can't get version from $file" >&2
+ exit 1
+fi
+
+base=$(basename $full .out)
+log=/tmp/$base.log$$
+if [ $is4 -ne 0 ]; then
+ $KEA4 -t $full >& $log
+ if [ $? -ne 0 ]; then
+ echo "$full raised an error" >&2
+ exit 1
+ fi
+fi
+if [ $is6 -ne 0 ]; then
+ $KEA6 -t $full >& $log
+ if [ $? -ne 0 ]; then
+ echo "$full raised an error" >&2
+ exit 1
+ fi
+fi
diff --git a/keama/tests/class4.in4 b/keama/tests/class4.in4
new file mode 100644
index 00000000..f573a02c
--- /dev/null
+++ b/keama/tests/class4.in4
@@ -0,0 +1,11 @@
+# class declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+
+# class declaration
+class "foobar" {
+ match if option mysystem = "version1";
+ option myversion 1;
+}
diff --git a/keama/tests/class4.out b/keama/tests/class4.out
new file mode 100644
index 00000000..41ddf27f
--- /dev/null
+++ b/keama/tests/class4.out
@@ -0,0 +1,36 @@
+{
+ # class declaration config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "mysystem",
+ "code": 250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # class declaration
+ {
+ "name": "foobar",
+ /// from: match if (option dhcp.mysystem) = 'version1'
+ "test": "option[250].hex == 'version1'",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/class4empty.in4 b/keama/tests/class4empty.in4
new file mode 100644
index 00000000..d0b9faa5
--- /dev/null
+++ b/keama/tests/class4empty.in4
@@ -0,0 +1,5 @@
+# void class declaration config
+
+# class declaration
+class "foobar" {
+}
diff --git a/keama/tests/class4empty.out b/keama/tests/class4empty.out
new file mode 100644
index 00000000..d2359856
--- /dev/null
+++ b/keama/tests/class4empty.out
@@ -0,0 +1,11 @@
+{
+ # void class declaration config
+ # class declaration
+ "Dhcp4": {
+ "client-classes": [
+ {
+ "name": "foobar"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/class6.in6 b/keama/tests/class6.in6
new file mode 100644
index 00000000..039a80c9
--- /dev/null
+++ b/keama/tests/class6.in6
@@ -0,0 +1,11 @@
+# class declaration config
+
+# options
+option dhcp6.mysystem code 1250 = text;
+option dhcp6.myversion code 1251 = unsigned integer 16;
+
+# class declaration
+class "foobar" {
+ match if option dhcp6.mysystem = "version1";
+ option dhcp6.myversion 1;
+}
diff --git a/keama/tests/class6.out b/keama/tests/class6.out
new file mode 100644
index 00000000..8c9af83d
--- /dev/null
+++ b/keama/tests/class6.out
@@ -0,0 +1,36 @@
+{
+ # class declaration config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "mysystem",
+ "code": 1250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # class declaration
+ {
+ "name": "foobar",
+ /// from: match if (option dhcp6.mysystem) = 'version1'
+ "test": "option[1250].hex == 'version1'",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/class6empty.in6 b/keama/tests/class6empty.in6
new file mode 100644
index 00000000..d0b9faa5
--- /dev/null
+++ b/keama/tests/class6empty.in6
@@ -0,0 +1,5 @@
+# void class declaration config
+
+# class declaration
+class "foobar" {
+}
diff --git a/keama/tests/class6empty.out b/keama/tests/class6empty.out
new file mode 100644
index 00000000..a9869b5f
--- /dev/null
+++ b/keama/tests/class6empty.out
@@ -0,0 +1,11 @@
+{
+ # void class declaration config
+ # class declaration
+ "Dhcp6": {
+ "client-classes": [
+ {
+ "name": "foobar"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/classbadmatch.err b/keama/tests/classbadmatch.err
new file mode 100644
index 00000000..b9eac948
--- /dev/null
+++ b/keama/tests/classbadmatch.err
@@ -0,0 +1,7 @@
+# bad (match with a boolean expression) class declaration config
+
+# class declaration
+class "foobar" {
+ match option server.duplicates = 0;
+ default-lease-time 1800;
+}
diff --git a/keama/tests/classbadmatch.msg b/keama/tests/classbadmatch.msg
new file mode 100644
index 00000000..5fcda249
--- /dev/null
+++ b/keama/tests/classbadmatch.msg
@@ -0,0 +1 @@
+classbadmatch.err line 5: Expecting a data expression.
diff --git a/keama/tests/classbadmatchif.err b/keama/tests/classbadmatchif.err
new file mode 100644
index 00000000..7eb88d65
--- /dev/null
+++ b/keama/tests/classbadmatchif.err
@@ -0,0 +1,7 @@
+# bad (match if with a data expression) class declaration config
+
+# class declaration
+class "foobar" {
+ match if option server.duplicates;
+ default-lease-time 1800;
+}
diff --git a/keama/tests/classbadmatchif.msg b/keama/tests/classbadmatchif.msg
new file mode 100644
index 00000000..073d48c2
--- /dev/null
+++ b/keama/tests/classbadmatchif.msg
@@ -0,0 +1 @@
+classbadmatchif.err line 5: Expecting a boolean expression.
diff --git a/keama/tests/classinclass.err b/keama/tests/classinclass.err
new file mode 100644
index 00000000..36aa0b4b
--- /dev/null
+++ b/keama/tests/classinclass.err
@@ -0,0 +1,10 @@
+# class declaration inside class declaration config
+
+# class declaration
+class "foobar" {
+ # can't put a class declaration here
+ subclass "foobar" "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/classinclass.msg b/keama/tests/classinclass.msg
new file mode 100644
index 00000000..5e1c26c9
--- /dev/null
+++ b/keama/tests/classinclass.msg
@@ -0,0 +1 @@
+classinclass.err line 6: class declarations not allowed here.
diff --git a/keama/tests/concatdx4.in4 b/keama/tests/concatdx4.in4
new file mode 100644
index 00000000..b94a3a2f
--- /dev/null
+++ b/keama/tests/concatdx4.in4
@@ -0,0 +1,19 @@
+# concat data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# use substring in a reductible match
+class "reductible" {
+ match concat("domain=", suffix(option host-name, 3));
+}
+
+subclass "reductible" "domain=com" { }
+
+# reduce literals too
+class "literal" {
+ match if option host-name = concat("www.", "example.", "com");
+}
+
+# raw
+option host-name = concat("www.", option domain-name);
diff --git a/keama/tests/concatdx4.out b/keama/tests/concatdx4.out
new file mode 100644
index 00000000..4602a497
--- /dev/null
+++ b/keama/tests/concatdx4.out
@@ -0,0 +1,48 @@
+{
+ # concat data expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # use substring in a reductible match
+ /// match: concat('domain=', suffix(option dhcp.host-name, 3))
+ {
+ "name": "reductible"
+ },
+ /// subclass selector 'domain=com'
+ {
+ "name": "sub#reductible#0",
+ /// from: match concat('domain=', suffix(option dhcp.host-name, 3))
+ /// data: 'domain=com'
+ "test": "concat('domain=', substring(option[12].hex,-3,all)) == 'domain=com'"
+ },
+ # reduce literals too
+ {
+ "name": "literal",
+ /// from: match if (option dhcp.host-name) = (concat('www.', concat('example.', 'com')))
+ "test": "option[12].hex == 'www.example.com'"
+ }
+ ],
+ "option-data": [
+// # raw
+// {
+// "space": "dhcp4",
+// "name": "host-name",
+// "code": 12,
+// "csv-format": false,
+// "expression": {
+// "concat": {
+// "left": "www.",
+// "right": {
+// "option": {
+// "universe": "dhcp",
+// "name": "domain-name",
+// "code": 15
+// }
+// }
+// }
+// }
+// }
+ ]
+ }
+}
diff --git a/keama/tests/concatnulldx4.in4 b/keama/tests/concatnulldx4.in4
new file mode 100644
index 00000000..9b5e2a42
--- /dev/null
+++ b/keama/tests/concatnulldx4.in4
@@ -0,0 +1,18 @@
+# concat with null argument data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# null left argument
+class "null-left" {
+ match concat("", suffix(option host-name, 3));
+}
+
+subclass "null-left" "com" { }
+
+# null right argument
+class "null-right" {
+ match concat(suffix(option host-name, 3), substring("foobar", 0, 0));
+}
+
+subclass "null-right" "org" { }
diff --git a/keama/tests/concatnulldx4.out b/keama/tests/concatnulldx4.out
new file mode 100644
index 00000000..66cdbdf8
--- /dev/null
+++ b/keama/tests/concatnulldx4.out
@@ -0,0 +1,33 @@
+{
+ # concat with null argument data expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # null left argument
+ /// match: concat('', suffix(option dhcp.host-name, 3))
+ {
+ "name": "null-left"
+ },
+ /// subclass selector 'com'
+ {
+ "name": "sub#null-left#0",
+ /// from: match concat('', suffix(option dhcp.host-name, 3))
+ /// data: 'com'
+ "test": "substring(option[12].hex,-3,all) == 'com'"
+ },
+ # null right argument
+ /// match: concat(suffix(option dhcp.host-name, 3), substring('foobar', 0, 0))
+ {
+ "name": "null-right"
+ },
+ /// subclass selector 'org'
+ {
+ "name": "sub#null-right#1",
+ /// from: match concat(suffix(option dhcp.host-name, 3), substring('foobar', 0, 0))
+ /// data: 'org'
+ "test": "substring(option[12].hex,-3,all) == 'org'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/configdata4.in4 b/keama/tests/configdata4.in4
new file mode 100644
index 00000000..f8c5c7bc
--- /dev/null
+++ b/keama/tests/configdata4.in4
@@ -0,0 +1,26 @@
+# config (aka server option space data config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# configs
+dynamic-bootp-lease-length 1200;
+
+boot-unknown-clients false;
+
+min-secs 20;
+
+lease-file-name "/tmp/leases";
+
+local-port 10067;
+
+local-address 10.5.5.1;
+
+# not quoted?
+omapi-key my.key.biz;
+
+limit-addrs-per-ia 12345;
+
+ddns-local-address6 2001::1;
+
+pid-file-name = "/tmp/pid";
diff --git a/keama/tests/configdata4.out b/keama/tests/configdata4.out
new file mode 100644
index 00000000..a1af336e
--- /dev/null
+++ b/keama/tests/configdata4.out
@@ -0,0 +1,74 @@
+{
+ # config (aka server option space data config
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// "config": [
+// /// bootp protocol is not supported
+// {
+// "name": "dynamic-bootp-lease-length",
+// "code": 5,
+// "value": 1200
+// },
+// /// bootp protocol is not supported
+// {
+// "name": "boot-unknown-clients",
+// "code": 6,
+// "value": false
+// },
+// /// min-secs is not (yet?) supported
+// /// Reference Kea #223
+// {
+// "name": "min-secs",
+// "code": 14,
+// "value": 5120
+// },
+// /// lease-file-name is an internal ISC DHCP feature
+// {
+// "name": "lease-file-name",
+// "code": 26,
+// "value": "/tmp/leases"
+// },
+// /// local-port is not supported
+// /// command line -p parameter should be used instead
+// {
+// "name": "local-port",
+// "code": 32,
+// "value": 10067
+// },
+// /// local-address is not supported
+// /// Kea equivalent feature is to specify an interface address
+// {
+// "name": "local-address",
+// "code": 35,
+// "value": "10.5.5.1"
+// },
+// /// omapi-key is an internal ISC DHCP feature
+// {
+// "name": "omapi-key",
+// "code": 36,
+// "value": "my.key.biz"
+// },
+// /// limit-addrs-per-ia is not (yet?) supported
+// /// Reference Kea #227
+// {
+// "name": "limit-addrs-per-ia",
+// "code": 56,
+// "value": 12345
+// },
+// /// ddns-local-address6 is not supported
+// /// Kea D2 equivalent config is ip-address
+// {
+// "name": "ddns-local-address6",
+// "code": 81,
+// "value": "2001::1"
+// },
+// /// pid-file-nam is an internal ISC DHCP feature
+// {
+// "name": "pid-file-name",
+// "code": 27,
+// "value": "/tmp/pid"
+// }
+// ]
+ }
+}
diff --git a/keama/tests/dbtimeformat4.in4 b/keama/tests/dbtimeformat4.in4
new file mode 100644
index 00000000..b3225a82
--- /dev/null
+++ b/keama/tests/dbtimeformat4.in4
@@ -0,0 +1,6 @@
+# db-time-format config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+db-time-format default;
diff --git a/keama/tests/dbtimeformat4.out b/keama/tests/dbtimeformat4.out
new file mode 100644
index 00000000..0988bfbd
--- /dev/null
+++ b/keama/tests/dbtimeformat4.out
@@ -0,0 +1,10 @@
+{
+ # db-time-format config
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// "statement": {
+// "db-time-format": "default"
+// }
+ }
+}
diff --git a/keama/tests/dbtimeformat6.in6 b/keama/tests/dbtimeformat6.in6
new file mode 100644
index 00000000..619d1c91
--- /dev/null
+++ b/keama/tests/dbtimeformat6.in6
@@ -0,0 +1,6 @@
+# db-time-format config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+db-time-format local;
diff --git a/keama/tests/dbtimeformat6.out b/keama/tests/dbtimeformat6.out
new file mode 100644
index 00000000..42460de6
--- /dev/null
+++ b/keama/tests/dbtimeformat6.out
@@ -0,0 +1,10 @@
+{
+ # db-time-format config
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800
+// "statement": {
+// "db-time-format": "local"
+// }
+ }
+}
diff --git a/keama/tests/ddnsupdstyle6.in6 b/keama/tests/ddnsupdstyle6.in6
new file mode 100644
index 00000000..ef23fe38
--- /dev/null
+++ b/keama/tests/ddnsupdstyle6.in6
@@ -0,0 +1,12 @@
+# ddns-update-style
+
+ddns-update-style standard;
+
+# embedded in pool
+subnet6 2001::/64 {
+ pool6 {
+ ddns-update-style interim;
+ range6 2001::1000 2001::1fff;
+ }
+}
+
diff --git a/keama/tests/ddnsupdstyle6.out b/keama/tests/ddnsupdstyle6.out
new file mode 100644
index 00000000..88323bb0
--- /dev/null
+++ b/keama/tests/ddnsupdstyle6.out
@@ -0,0 +1,29 @@
+{
+ # ddns-update-style
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "dhcp-ddns": {
+ /// Unspecified ddns-domainname (default domain-name option value)
+ /// Kea requires a qualifying-suffix
+ /// Initialized to "": please put a value
+ "qualifying-suffix": "",
+ "enable-updates": true
+ },
+ "subnet6": [
+ # embedded in pool
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ {
+// /// Unsupported ddns-update-style interim
+// /// Only global ddns-update-style is supported
+// "ddns-update-style": "interim",
+ "pool": "2001::1000 - 2001::1fff"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/defaultexpr6.in6 b/keama/tests/defaultexpr6.in6
new file mode 100644
index 00000000..e81bd8d3
--- /dev/null
+++ b/keama/tests/defaultexpr6.in6
@@ -0,0 +1,10 @@
+# default expressions
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# default expression is a variable reference
+foo;
+
+# or a function call when there are parentheses
+bar ("abcd", "xyxt");
diff --git a/keama/tests/defaultexpr6.out b/keama/tests/defaultexpr6.out
new file mode 100644
index 00000000..8646e8af
--- /dev/null
+++ b/keama/tests/defaultexpr6.out
@@ -0,0 +1,25 @@
+{
+ # default expressions
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800
+// # default expression is a variable reference
+// "statement": {
+// "eval": {
+// "variable-reference": "foo"
+// }
+// }
+// # or a function call when there are parentheses
+// "statement": {
+// "eval": {
+// "funcall": {
+// "name": "bar",
+// "arguments": [
+// "abcd",
+// "xyxt"
+// ]
+// }
+// }
+// }
+ }
+}
diff --git a/keama/tests/denyunknown6.in6 b/keama/tests/denyunknown6.in6
new file mode 100644
index 00000000..ccd5541a
--- /dev/null
+++ b/keama/tests/denyunknown6.in6
@@ -0,0 +1,15 @@
+# DHCPv6 deny unknown client config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# subnet declaration
+subnet6 2001::/64 {
+ # pool declaration
+ pool6 {
+ # avoid empty pool
+ range6 2001::100 2001::200;
+ # call get_permit
+ deny unknown clients;
+ }
+}
diff --git a/keama/tests/denyunknown6.out b/keama/tests/denyunknown6.out
new file mode 100644
index 00000000..68db27b7
--- /dev/null
+++ b/keama/tests/denyunknown6.out
@@ -0,0 +1,32 @@
+{
+ # DHCPv6 deny unknown client config
+ # empty configs are not accepted by Kea
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "subnet6": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "2001::100 - 2001::200",
+ /// From:
+ /// deny unknown clients
+ "client-class": "gen#_AND_#KNOWN#"
+ }
+ ]
+ }
+ ],
+ "client-classes": [
+ {
+ "name": "gen#_AND_#KNOWN#",
+ "test": "member('KNOWN')"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/docsis4.dir b/keama/tests/docsis4.dir
new file mode 100644
index 00000000..82b206ef
--- /dev/null
+++ b/keama/tests/docsis4.dir
@@ -0,0 +1,11 @@
+# DOCSIS DHCPv4 vendor space
+
+option space docsis;
+
+option vendor.docsis code 4491 = encapsulate docsis;
+
+option docsis.oro code 1 = array of unsigned integer 8;
+option docsis.tftp-servers code 2 = array of ip-address;
+
+% option docsis.oro local;
+% option docsis.tftp-servers local;
diff --git a/keama/tests/docsis6.dir b/keama/tests/docsis6.dir
new file mode 100644
index 00000000..ff7cd62a
--- /dev/null
+++ b/keama/tests/docsis6.dir
@@ -0,0 +1,27 @@
+# DOCSIS DHCPv6 vendor space
+
+option space docsis;
+
+option vsio.docsis code 4491 = encapsulate docsis;
+
+option docsis.oro code 1 = array of unsigned integer 16;
+option docsis.device-type code 2 = text;
+option docsis.vendor-type code 10 = text;
+option docsis.tftp-servers code 32 = array of ip6-address;
+option docsis.config-file code 33 = text;
+option docsis.syslog-servers code 34 = array of ip6-address;
+% option docsis.device-id code 36 = "X";
+option docsis.time-servers code 37 = array of ip6-address;
+option docsis.time-offset code 38 = unsigned integer 32;
+% option docsis.cmts-cm-mac code 1026 = "X";
+
+% option docsis.oro local;
+% option docsis.device-type local;
+% option docsis.vendor-type local;
+% option docsis.tftp-servers local;
+% option docsis.config-file local;
+% option docsis.syslog-servers local;
+% option docsis.device-id local;
+% option docsis.time-servers local;
+% option docsis.time-offset local;
+% option docsis.cmts-cm-mac local;
diff --git a/keama/tests/duid2.err b/keama/tests/duid2.err
new file mode 100644
index 00000000..fcbef592
--- /dev/null
+++ b/keama/tests/duid2.err
@@ -0,0 +1,7 @@
+# two server duid config
+
+# EN server duid declaration
+server-duid en 2495 "enterprise-specific-identifier-1234";
+
+# LL server duid declaration
+server-duid ll ethernet 00:16:6F:49:7D:9B;
diff --git a/keama/tests/duid2.msg b/keama/tests/duid2.msg
new file mode 100644
index 00000000..06a8a00f
--- /dev/null
+++ b/keama/tests/duid2.msg
@@ -0,0 +1 @@
+duid2.err line 7: there is already a server-id
diff --git a/keama/tests/duiden6.in6 b/keama/tests/duiden6.in6
new file mode 100644
index 00000000..ae8385ea
--- /dev/null
+++ b/keama/tests/duiden6.in6
@@ -0,0 +1,4 @@
+# EN server duid config
+
+# EN server duid declaration
+server-duid en 2495 "enterprise-specific-identifier-1234";
diff --git a/keama/tests/duiden6.out b/keama/tests/duiden6.out
new file mode 100644
index 00000000..1e7e3021
--- /dev/null
+++ b/keama/tests/duiden6.out
@@ -0,0 +1,11 @@
+{
+ # EN server duid config
+ # EN server duid declaration
+ "Dhcp6": {
+ "server-id": {
+ "type": "EN",
+ "enterprise-id": 2495,
+ "identifier": "656e74657270726973652d73706563696669632d6964656e7469666965722d31323334"
+ }
+ }
+}
diff --git a/keama/tests/duidennoid.err b/keama/tests/duidennoid.err
new file mode 100644
index 00000000..ae6d12ae
--- /dev/null
+++ b/keama/tests/duidennoid.err
@@ -0,0 +1,5 @@
+# bad (no identifier) EN server duid config
+
+# EN server duid declaration
+server-duid en 2495;
+
diff --git a/keama/tests/duidennoid.msg b/keama/tests/duidennoid.msg
new file mode 100644
index 00000000..054fa65e
--- /dev/null
+++ b/keama/tests/duidennoid.msg
@@ -0,0 +1 @@
+duidennoid.err line 4: identifier expected
diff --git a/keama/tests/duidennonum.err b/keama/tests/duidennonum.err
new file mode 100644
index 00000000..abdfdd7c
--- /dev/null
+++ b/keama/tests/duidennonum.err
@@ -0,0 +1,4 @@
+# bad (no number) EN server duid config
+
+# EN server duid declaration
+server-duid en "enterprise-specific-identifier-1234";
diff --git a/keama/tests/duidennonum.msg b/keama/tests/duidennonum.msg
new file mode 100644
index 00000000..941a0d03
--- /dev/null
+++ b/keama/tests/duidennonum.msg
@@ -0,0 +1 @@
+duidennonum.err line 4: enterprise number expected
diff --git a/keama/tests/duidll6.in6 b/keama/tests/duidll6.in6
new file mode 100644
index 00000000..fac38c7a
--- /dev/null
+++ b/keama/tests/duidll6.in6
@@ -0,0 +1,5 @@
+# LL server duid config
+
+# LL server duid declaration
+server-duid ll;
+
diff --git a/keama/tests/duidll6.out b/keama/tests/duidll6.out
new file mode 100644
index 00000000..089539d7
--- /dev/null
+++ b/keama/tests/duidll6.out
@@ -0,0 +1,9 @@
+{
+ # LL server duid config
+ # LL server duid declaration
+ "Dhcp6": {
+ "server-id": {
+ "type": "LL"
+ }
+ }
+}
diff --git a/keama/tests/duidllbadtype.err b/keama/tests/duidllbadtype.err
new file mode 100644
index 00000000..2526f6e1
--- /dev/null
+++ b/keama/tests/duidllbadtype.err
@@ -0,0 +1,4 @@
+# bad (unknown hardware type) LL server duid config
+
+# LL server duid declaration
+server-duid ll foobar 00:16:6F:49:7D:9B;
diff --git a/keama/tests/duidllbadtype.msg b/keama/tests/duidllbadtype.msg
new file mode 100644
index 00000000..341ebd0b
--- /dev/null
+++ b/keama/tests/duidllbadtype.msg
@@ -0,0 +1 @@
+duidllbadtype.err line 4: hardware type expected
diff --git a/keama/tests/duidllhw6.in6 b/keama/tests/duidllhw6.in6
new file mode 100644
index 00000000..48312801
--- /dev/null
+++ b/keama/tests/duidllhw6.in6
@@ -0,0 +1,6 @@
+# LL server duid config
+
+# LL server duid declaration
+server-duid ll ethernet 00:16:6F:49:7D:9B;
+
+
diff --git a/keama/tests/duidllhw6.out b/keama/tests/duidllhw6.out
new file mode 100644
index 00000000..ad7fbdac
--- /dev/null
+++ b/keama/tests/duidllhw6.out
@@ -0,0 +1,11 @@
+{
+ # LL server duid config
+ # LL server duid declaration
+ "Dhcp6": {
+ "server-id": {
+ "type": "LL",
+ "htype": 1,
+ "identifier": "00166f497d9b"
+ }
+ }
+}
diff --git a/keama/tests/duidllnohw.err b/keama/tests/duidllnohw.err
new file mode 100644
index 00000000..a93b90d3
--- /dev/null
+++ b/keama/tests/duidllnohw.err
@@ -0,0 +1,4 @@
+# bad (no hardware address) LL server duid config
+
+# LL server duid declaration
+server-duid ll fddi;
diff --git a/keama/tests/duidllnohw.msg b/keama/tests/duidllnohw.msg
new file mode 100644
index 00000000..b2d955ec
--- /dev/null
+++ b/keama/tests/duidllnohw.msg
@@ -0,0 +1 @@
+duidllnohw.err line 4: expecting hexadecimal number.
diff --git a/keama/tests/duidllt6.in6 b/keama/tests/duidllt6.in6
new file mode 100644
index 00000000..25420b3c
--- /dev/null
+++ b/keama/tests/duidllt6.in6
@@ -0,0 +1,5 @@
+# LLT server duid config
+
+# LLT server duid declaration
+server-duid llt;
+
diff --git a/keama/tests/duidllt6.out b/keama/tests/duidllt6.out
new file mode 100644
index 00000000..2a1ea79e
--- /dev/null
+++ b/keama/tests/duidllt6.out
@@ -0,0 +1,9 @@
+{
+ # LLT server duid config
+ # LLT server duid declaration
+ "Dhcp6": {
+ "server-id": {
+ "type": "LLT"
+ }
+ }
+}
diff --git a/keama/tests/duidlltbadtype.err b/keama/tests/duidlltbadtype.err
new file mode 100644
index 00000000..66ab6642
--- /dev/null
+++ b/keama/tests/duidlltbadtype.err
@@ -0,0 +1,4 @@
+# bad (unknown hardware type) LLT server duid config
+
+# LLT server duid declaration
+server-duid llt foobar 213982198 00:16:6F:49:7D:9B;
diff --git a/keama/tests/duidlltbadtype.msg b/keama/tests/duidlltbadtype.msg
new file mode 100644
index 00000000..32305a75
--- /dev/null
+++ b/keama/tests/duidlltbadtype.msg
@@ -0,0 +1 @@
+duidlltbadtype.err line 4: hardware type expected
diff --git a/keama/tests/duidlltnohw.err b/keama/tests/duidlltnohw.err
new file mode 100644
index 00000000..3208ed60
--- /dev/null
+++ b/keama/tests/duidlltnohw.err
@@ -0,0 +1,4 @@
+# bad (no hardware address) LLT server duid config
+
+# LLT server duid declaration
+server-duid llt token-ring 213982198;
diff --git a/keama/tests/duidlltnohw.msg b/keama/tests/duidlltnohw.msg
new file mode 100644
index 00000000..7bfaa245
--- /dev/null
+++ b/keama/tests/duidlltnohw.msg
@@ -0,0 +1 @@
+duidlltnohw.err line 4: expecting hexadecimal number.
diff --git a/keama/tests/duidlltnotime.err b/keama/tests/duidlltnotime.err
new file mode 100644
index 00000000..f53321bb
--- /dev/null
+++ b/keama/tests/duidlltnotime.err
@@ -0,0 +1,4 @@
+# bad (no timestamp) LLT server duid config
+
+# LLT server duid declaration
+server-duid llt token-ring A8:16:6F:49:7D:9B;
diff --git a/keama/tests/duidlltnotime.msg b/keama/tests/duidlltnotime.msg
new file mode 100644
index 00000000..2b7fb8a3
--- /dev/null
+++ b/keama/tests/duidlltnotime.msg
@@ -0,0 +1 @@
+duidlltnotime.err line 4: timestamp expected
diff --git a/keama/tests/duidlltthw4.err4 b/keama/tests/duidlltthw4.err4
new file mode 100644
index 00000000..ae039d18
--- /dev/null
+++ b/keama/tests/duidlltthw4.err4
@@ -0,0 +1,4 @@
+# LLT server duid config
+
+# LLT server duid declaration
+server-duid llt token-ring 213982198 00:16:6F:49:7D:9B;
diff --git a/keama/tests/duidlltthw4.msg b/keama/tests/duidlltthw4.msg
new file mode 100644
index 00000000..df163bb1
--- /dev/null
+++ b/keama/tests/duidlltthw4.msg
@@ -0,0 +1 @@
+duidlltthw4.err4 line 4: expecting a parameter or declaration
diff --git a/keama/tests/duidlltthw6.in6 b/keama/tests/duidlltthw6.in6
new file mode 100644
index 00000000..ae039d18
--- /dev/null
+++ b/keama/tests/duidlltthw6.in6
@@ -0,0 +1,4 @@
+# LLT server duid config
+
+# LLT server duid declaration
+server-duid llt token-ring 213982198 00:16:6F:49:7D:9B;
diff --git a/keama/tests/duidlltthw6.out b/keama/tests/duidlltthw6.out
new file mode 100644
index 00000000..de2d0a48
--- /dev/null
+++ b/keama/tests/duidlltthw6.out
@@ -0,0 +1,12 @@
+{
+ # LLT server duid config
+ # LLT server duid declaration
+ "Dhcp6": {
+ "server-id": {
+ "type": "LLT",
+ "htype": 6,
+ "time": 213982198,
+ "identifier": "00166f497d9b"
+ }
+ }
+}
diff --git a/keama/tests/duidnoid.err b/keama/tests/duidnoid.err
new file mode 100644
index 00000000..32a2c9cb
--- /dev/null
+++ b/keama/tests/duidnoid.err
@@ -0,0 +1,4 @@
+# bad (no identifier) numeric server duid config
+
+# server duid declaration
+server-duid 9;
diff --git a/keama/tests/duidnoid.msg b/keama/tests/duidnoid.msg
new file mode 100644
index 00000000..3e44395a
--- /dev/null
+++ b/keama/tests/duidnoid.msg
@@ -0,0 +1 @@
+duidnoid.err line 4: identifier expected
diff --git a/keama/tests/enableupdates6.in6 b/keama/tests/enableupdates6.in6
new file mode 100644
index 00000000..b6641957
--- /dev/null
+++ b/keama/tests/enableupdates6.in6
@@ -0,0 +1,8 @@
+# ddns-updates (aka enable-updates)
+
+ddns-updates on;
+
+# embedded
+class "foo" {
+ ddns-updates off;
+}
diff --git a/keama/tests/enableupdates6.out b/keama/tests/enableupdates6.out
new file mode 100644
index 00000000..8d20a773
--- /dev/null
+++ b/keama/tests/enableupdates6.out
@@ -0,0 +1,20 @@
+{
+ # ddns-updates (aka enable-updates)
+ "Dhcp6": {
+ "dhcp-ddns": {
+ /// Unspecified ddns-domainname (default domain-name option value)
+ /// Kea requires a qualifying-suffix
+ /// Initialized to "": please put a value
+ "qualifying-suffix": "",
+ "enable-updates": true
+ },
+ "client-classes": [
+ # embedded
+ {
+ "name": "foo"
+// /// Only global enable-updates is supported
+// "enable-updates": false
+ }
+ ]
+ }
+}
diff --git a/keama/tests/encodedx6.in6 b/keama/tests/encodedx6.in6
new file mode 100644
index 00000000..f6b16377
--- /dev/null
+++ b/keama/tests/encodedx6.in6
@@ -0,0 +1,9 @@
+# encode data expression and extract numeric expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# reduce literals
+class "literal" {
+ match if option dhcp6.client-data != encode-int(extract-int("\bbar",32),16);
+}
diff --git a/keama/tests/encodedx6.out b/keama/tests/encodedx6.out
new file mode 100644
index 00000000..d1b8b38a
--- /dev/null
+++ b/keama/tests/encodedx6.out
@@ -0,0 +1,15 @@
+{
+ # encode data expression and extract numeric expression
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # reduce literals
+ {
+ "name": "literal",
+ /// from: match if (option dhcp6.client-data) != (encode-int(extract-int('bar', 32), 16))
+ "test": "not (option[45].hex == 'ar')"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/env b/keama/tests/env
new file mode 100644
index 00000000..9fe0fcd4
--- /dev/null
+++ b/keama/tests/env
@@ -0,0 +1,3 @@
+setenv KEA4 /tmp/kea/src/bin/dhcp4/kea-dhcp4
+setenv KEA6 /tmp/kea/src/bin/dhcp6/kea-dhcp6
+setenv HOOK /tmp/kea/premium/src/hooks/dhcp/flex_id/.libs/
diff --git a/keama/tests/escapestring4.in4 b/keama/tests/escapestring4.in4
new file mode 100644
index 00000000..3f318e6c
--- /dev/null
+++ b/keama/tests/escapestring4.in4
@@ -0,0 +1,6 @@
+# string option-data with embedded commas
+
+# vendor option space
+option a-string code 250 = text;
+
+option a-string "foo, bar";
diff --git a/keama/tests/escapestring4.out b/keama/tests/escapestring4.out
new file mode 100644
index 00000000..caef76c3
--- /dev/null
+++ b/keama/tests/escapestring4.out
@@ -0,0 +1,23 @@
+{
+ # string option-data with embedded commas
+ # vendor option space
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "a-string",
+ "code": 250,
+ "type": "string"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "a-string",
+ "code": 250,
+// "original-data": "\"foo, bar\"",
+ "data": "foo\\, bar"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/execstatement4.in4 b/keama/tests/execstatement4.in4
new file mode 100644
index 00000000..6adc6b1e
--- /dev/null
+++ b/keama/tests/execstatement4.in4
@@ -0,0 +1,7 @@
+# DHCPv4 executable statement config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# impossible to convert statement statement
+break;
diff --git a/keama/tests/execstatement4.out b/keama/tests/execstatement4.out
new file mode 100644
index 00000000..4988de92
--- /dev/null
+++ b/keama/tests/execstatement4.out
@@ -0,0 +1,11 @@
+{
+ # DHCPv4 executable statement config
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// # impossible to convert statement statement
+// "statement": {
+// "break": null
+// }
+ }
+}
diff --git a/keama/tests/execstatement6.in6 b/keama/tests/execstatement6.in6
new file mode 100644
index 00000000..fe49424a
--- /dev/null
+++ b/keama/tests/execstatement6.in6
@@ -0,0 +1,7 @@
+# DHCPv6 executable statement config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# impossible to convert statement statement
+break;
diff --git a/keama/tests/execstatement6.out b/keama/tests/execstatement6.out
new file mode 100644
index 00000000..25ac01af
--- /dev/null
+++ b/keama/tests/execstatement6.out
@@ -0,0 +1,11 @@
+{
+ # DHCPv6 executable statement config
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800
+// # impossible to convert statement statement
+// "statement": {
+// "break": null
+// }
+ }
+}
diff --git a/keama/tests/existsbx4.in4 b/keama/tests/existsbx4.in4
new file mode 100644
index 00000000..650a208e
--- /dev/null
+++ b/keama/tests/existsbx4.in4
@@ -0,0 +1,15 @@
+# exists boolean expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# use exists in a reductible match if
+class "reductible" {
+ match if exists host-name;
+}
+
+# if test is a boolean too
+if exists host-name {
+ log(info, concat("hostname:", option host-name));
+}
+
diff --git a/keama/tests/existsbx4.out b/keama/tests/existsbx4.out
new file mode 100644
index 00000000..7d977ac6
--- /dev/null
+++ b/keama/tests/existsbx4.out
@@ -0,0 +1,48 @@
+{
+ # exists boolean expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # use exists in a reductible match if
+ {
+ "name": "reductible",
+ /// from: match if exists dhcp.host-name
+ "test": "option[12].exists"
+ }
+ ]
+// # if test is a boolean too
+// "statement": {
+// "if": {
+// "condition": {
+// "exists": {
+// "universe": "dhcp",
+// "name": "host-name",
+// "code": 12
+// }
+// },
+// "then": [
+// {
+// /// Kea does not support yet log statements
+// /// Reference Kea #234
+// "log": {
+// "priority": "info",
+// "message": {
+// "concat": {
+// "left": "hostname:",
+// "right": {
+// "option": {
+// "universe": "dhcp",
+// "name": "host-name",
+// "code": 12
+// }
+// }
+// }
+// }
+// }
+// }
+// ]
+// }
+// }
+ }
+}
diff --git a/keama/tests/filename4.in4 b/keama/tests/filename4.in4
new file mode 100644
index 00000000..9bf3ad00
--- /dev/null
+++ b/keama/tests/filename4.in4
@@ -0,0 +1,10 @@
+# filename (aka boot-file-name) and server-name (aka server-hostname)
+
+filename "/var/boot/boot1";
+server-name "foobar.biz";
+
+# embedded
+class "foo" {
+ filename "/var/boot/boot2";
+ server-name "none.biz";
+}
diff --git a/keama/tests/filename4.out b/keama/tests/filename4.out
new file mode 100644
index 00000000..a391eca5
--- /dev/null
+++ b/keama/tests/filename4.out
@@ -0,0 +1,17 @@
+{
+ # filename (aka boot-file-name) and server-name (aka server-hostname)
+ "Dhcp4": {
+// /// boot-file-name was defined in an unsupported scope
+// "boot-file-name": "/var/boot/boot1",
+// /// server-hostname was defined in an unsupported scope
+// "server-hostname": "foobar.biz",
+ "client-classes": [
+ # embedded
+ {
+ "name": "foo",
+ "boot-file-name": "/var/boot/boot2",
+ "server-hostname": "none.biz"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/filenamedx4.notyet b/keama/tests/filenamedx4.notyet
new file mode 100644
index 00000000..127bcc7a
--- /dev/null
+++ b/keama/tests/filenamedx4.notyet
@@ -0,0 +1,20 @@
+# filename data expression
+# Kea has no filename extractor in libeval
+
+# authoritative is mandatory
+authoritative;
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# by filename superclass
+class "byfn" {
+ match filename;
+}
+
+subclass "byfn" "boot00070e364819" {
+ option host-name "test1";
+}
+
+# raw
+option host-name = concat("host-", substring(filename, 4, 12));
diff --git a/keama/tests/fixedaddressinroot4.err4 b/keama/tests/fixedaddressinroot4.err4
new file mode 100644
index 00000000..f5d2480a
--- /dev/null
+++ b/keama/tests/fixedaddressinroot4.err4
@@ -0,0 +1,4 @@
+# DHCPv4 fixed address declaration in root config
+
+# DHCPv4 fixed address declaration must be in a host declaration
+fixed-address 204.152.185.133;
diff --git a/keama/tests/fixedaddressinroot4.msg b/keama/tests/fixedaddressinroot4.msg
new file mode 100644
index 00000000..fd0424a5
--- /dev/null
+++ b/keama/tests/fixedaddressinroot4.msg
@@ -0,0 +1 @@
+fixedaddressinroot4.err4 line 4: fixed-address parameter not allowed here.
diff --git a/keama/tests/fixedaddressinroot6.err6 b/keama/tests/fixedaddressinroot6.err6
new file mode 100644
index 00000000..f42854a7
--- /dev/null
+++ b/keama/tests/fixedaddressinroot6.err6
@@ -0,0 +1,4 @@
+# DHCPv6 fixed address declaration in root config
+
+# DHCPv6 fixed address declaration must be in a host declaration
+fixed-address6 2001::1;
diff --git a/keama/tests/fixedaddressinroot6.msg b/keama/tests/fixedaddressinroot6.msg
new file mode 100644
index 00000000..21da6d84
--- /dev/null
+++ b/keama/tests/fixedaddressinroot6.msg
@@ -0,0 +1 @@
+fixedaddressinroot6.err6 line 4: fixed-address parameter not allowed here.
diff --git a/keama/tests/fixedprefixinroot.err6 b/keama/tests/fixedprefixinroot.err6
new file mode 100644
index 00000000..7415aaf3
--- /dev/null
+++ b/keama/tests/fixedprefixinroot.err6
@@ -0,0 +1,4 @@
+# DHCPv6 fixed prefix declaration in root config
+
+# DHCPv6 fixed prefix declaration must be in a host declaration
+fixed-prefix6 2001:0:0:1/64;
diff --git a/keama/tests/fixedprefixinroot.msg b/keama/tests/fixedprefixinroot.msg
new file mode 100644
index 00000000..0b835acd
--- /dev/null
+++ b/keama/tests/fixedprefixinroot.msg
@@ -0,0 +1 @@
+fixedprefixinroot.err6 line 4: fixed-prefix6 declaration not allowed here.
diff --git a/keama/tests/fqdncompressed.err6 b/keama/tests/fqdncompressed.err6
new file mode 100644
index 00000000..aed1fe63
--- /dev/null
+++ b/keama/tests/fqdncompressed.err6
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+
+# compressed list of FQDNs are forbidden in DHCPv6
+option foobar.compressed-list code 1 = domain-list compressed;
diff --git a/keama/tests/fqdncompressed.msg b/keama/tests/fqdncompressed.msg
new file mode 100644
index 00000000..cfd157ef
--- /dev/null
+++ b/keama/tests/fqdncompressed.msg
@@ -0,0 +1 @@
+fqdncompressed.err6 line 7: domain list in DHCPv6 MUST NOT be compressed
diff --git a/keama/tests/gethostdx4.notyet b/keama/tests/gethostdx4.notyet
new file mode 100644
index 00000000..567d66a4
--- /dev/null
+++ b/keama/tests/gethostdx4.notyet
@@ -0,0 +1,13 @@
+# gethostname and gethostbyname data expressions
+
+# authoritative is mandatory
+authoritative;
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# gethostname
+option domain-name = suffix(gethostname(), (1 + 2) * 2);
+
+# gethostbyaddr
+option ntp-servers = gethostbyname("www.apple.fr");
diff --git a/keama/tests/global4.in4 b/keama/tests/global4.in4
new file mode 100644
index 00000000..ddfaec67
--- /dev/null
+++ b/keama/tests/global4.in4
@@ -0,0 +1,10 @@
+# DHCPv4 global reservation config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# global reservation
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ option ip-forwarding off;
+}
diff --git a/keama/tests/global4.out b/keama/tests/global4.out
new file mode 100644
index 00000000..66b380ff
--- /dev/null
+++ b/keama/tests/global4.out
@@ -0,0 +1,28 @@
+{
+ # DHCPv4 global reservation config
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "host-reservation-identifiers": [
+ "hw-address"
+ ],
+ "reservation-mode": "global",
+ "reservations": [
+ # global reservation
+ {
+ "hostname": "foobar",
+ "hw-address": "00:0b:fd:32:e6:fa",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "ip-forwarding",
+ "code": 19,
+// "original-data": "off",
+ /// canonized booleans to lowercase true or false
+ "data": "false"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/global6.in6 b/keama/tests/global6.in6
new file mode 100644
index 00000000..8bba7082
--- /dev/null
+++ b/keama/tests/global6.in6
@@ -0,0 +1,10 @@
+# DHCPv6 global reservation config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# global reservation
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ option dhcp6.name-servers 2a01:e00::2, 2a01:e00::1;
+}
diff --git a/keama/tests/global6.out b/keama/tests/global6.out
new file mode 100644
index 00000000..5616e7ec
--- /dev/null
+++ b/keama/tests/global6.out
@@ -0,0 +1,26 @@
+{
+ # DHCPv6 global reservation config
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "host-reservation-identifiers": [
+ "hw-address"
+ ],
+ "reservation-mode": "global",
+ "reservations": [
+ # global reservation
+ {
+ "hostname": "foobar",
+ "hw-address": "00:0b:fd:32:e6:fa",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "dns-servers",
+ "code": 23,
+ "data": "2a01:e00::2, 2a01:e00::1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/groupclass4.in4 b/keama/tests/groupclass4.in4
new file mode 100644
index 00000000..b306f66f
--- /dev/null
+++ b/keama/tests/groupclass4.in4
@@ -0,0 +1,32 @@
+# group and class declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ match option mysystem;
+ option myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" "version1";
+
+group machin {
+ next-server 10.10.10.1;
+ # this option is not propagated because the superclass takes precedence
+ option myversion 99;
+
+ # option setting subclass declaration
+ subclass "foobar" "version2" { option myversion 2; }
+
+ # complex subclass declaration
+ subclass "foobar" "version3" {
+ option myversion 3;
+ next-server 192.168.0.1;
+ }
+
+ # another simple subclass declaration
+ subclass "foobar" "version10";
+}
diff --git a/keama/tests/groupclass4.out b/keama/tests/groupclass4.out
new file mode 100644
index 00000000..71e40072
--- /dev/null
+++ b/keama/tests/groupclass4.out
@@ -0,0 +1,102 @@
+{
+ # group and class declaration config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "mysystem",
+ "code": 250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp.mysystem
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 'version1'
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version1'
+ "test": "option[250].hex == 'version1'"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'version2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "2"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version2'
+ "test": "option[250].hex == 'version2'",
+ "next-server": "10.10.10.1"
+ },
+ # complex subclass declaration
+ /// subclass selector 'version3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "3"
+ }
+ ],
+ "next-server": "192.168.0.1",
+ /// from: match option dhcp.mysystem
+ /// data: 'version3'
+ "test": "option[250].hex == 'version3'"
+ },
+ # another simple subclass declaration
+ /// subclass selector 'version10'
+ {
+ "name": "sub#foobar#3",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version10'
+ "test": "option[250].hex == 'version10'",
+ "next-server": "10.10.10.1"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/groupclass6.in6 b/keama/tests/groupclass6.in6
new file mode 100644
index 00000000..4cc21b78
--- /dev/null
+++ b/keama/tests/groupclass6.in6
@@ -0,0 +1,35 @@
+# group and class declaration config
+
+# options
+option dhcp6.mysystem code 1250 = text;
+option dhcp6.myversion code 1251 = unsigned integer 16;
+option dhcp6.myvalue code 1252 = text;
+
+# superclass declaration
+class "foobar" {
+ match option dhcp6.mysystem;
+ option dhcp6.myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" "version1";
+
+# anonymous group
+group {
+ # this option is not propagated because the superclass takes precedence
+ option dhcp6.myversion 99;
+
+ option dhcp6.myvalue "foo";
+
+ # option setting subclass declaration
+ subclass "foobar" "version2" { option dhcp6.myversion 2; }
+
+ # complex subclass declaration
+ subclass "foobar" "version3" {
+ option dhcp6.myversion 3;
+ option dhcp6.myvalue "bar";
+ }
+
+ # another simple subclass declaration
+ subclass "foobar" "version10";
+}
diff --git a/keama/tests/groupclass6.out b/keama/tests/groupclass6.out
new file mode 100644
index 00000000..68144b89
--- /dev/null
+++ b/keama/tests/groupclass6.out
@@ -0,0 +1,123 @@
+{
+ # group and class declaration config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "mysystem",
+ "code": 1250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "type": "uint16"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myvalue",
+ "code": 1252,
+ "type": "string"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp6.mysystem
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 'version1'
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version1'
+ "test": "option[1250].hex == 'version1'"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'version2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "2"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myvalue",
+ "code": 1252,
+ "data": "foo"
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version2'
+ "test": "option[1250].hex == 'version2'"
+ },
+ # complex subclass declaration
+ /// subclass selector 'version3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "3"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myvalue",
+ "code": 1252,
+ "data": "bar"
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version3'
+ "test": "option[1250].hex == 'version3'"
+ },
+ # another simple subclass declaration
+ /// subclass selector 'version10'
+ {
+ "name": "sub#foobar#3",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myvalue",
+ "code": 1252,
+ "data": "foo"
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version10'
+ "test": "option[1250].hex == 'version10'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/groupgroup4.in4 b/keama/tests/groupgroup4.in4
new file mode 100644
index 00000000..3be93d7d
--- /dev/null
+++ b/keama/tests/groupgroup4.in4
@@ -0,0 +1,45 @@
+# multiple groups declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+option myvalue code 252 = text;
+
+# superclass declaration
+class "foobar" {
+ match option mysystem;
+ option myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" "version1";
+
+group first {
+ next-server 10.10.10.1;
+ # this option is not propagated because the superclass takes precedence
+ option myversion 99;
+
+ # option setting subclass declaration
+ subclass "foobar" "version2" { option myversion 2; }
+
+ # complex subclass declaration
+ subclass "foobar" "version3" {
+ option myversion 3;
+ next-server 192.168.0.1;
+ }
+
+ group second {
+ # another simple subclass declaration
+ subclass "foobar" "version10";
+
+ # and a final subclass declaration
+ subclass "foobar" "version20" {
+ option myversion 20;
+ next-server 192.168.0.20;
+ option myvalue "twenty";
+ }
+
+ # positions of delaration do not matter
+ option myvalue "ten";
+ }
+}
diff --git a/keama/tests/groupgroup4.out b/keama/tests/groupgroup4.out
new file mode 100644
index 00000000..09dd0574
--- /dev/null
+++ b/keama/tests/groupgroup4.out
@@ -0,0 +1,138 @@
+{
+ # multiple groups declaration config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "mysystem",
+ "code": 250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "type": "uint16"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myvalue",
+ "code": 252,
+ "type": "string"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp.mysystem
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 'version1'
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version1'
+ "test": "option[250].hex == 'version1'"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'version2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "2"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version2'
+ "test": "option[250].hex == 'version2'",
+ "next-server": "10.10.10.1"
+ },
+ # complex subclass declaration
+ /// subclass selector 'version3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "3"
+ }
+ ],
+ "next-server": "192.168.0.1",
+ /// from: match option dhcp.mysystem
+ /// data: 'version3'
+ "test": "option[250].hex == 'version3'"
+ },
+ # another simple subclass declaration
+ /// subclass selector 'version10'
+ {
+ "name": "sub#foobar#3",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ },
+ # positions of delaration do not matter
+ {
+ "space": "dhcp4",
+ "name": "myvalue",
+ "code": 252,
+ "data": "ten"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version10'
+ "test": "option[250].hex == 'version10'",
+ "next-server": "10.10.10.1"
+ },
+ # and a final subclass declaration
+ /// subclass selector 'version20'
+ {
+ "name": "sub#foobar#4",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "20"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myvalue",
+ "code": 252,
+ "data": "twenty"
+ }
+ ],
+ "next-server": "192.168.0.20",
+ /// from: match option dhcp.mysystem
+ /// data: 'version20'
+ "test": "option[250].hex == 'version20'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/grouphost4.inn b/keama/tests/grouphost4.inn
new file mode 100644
index 00000000..da9d5291
--- /dev/null
+++ b/keama/tests/grouphost4.inn
@@ -0,0 +1,35 @@
+# group and host declarations config
+
+# subnet4 declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ range 10.5.5.5 10.5.5.10;
+}
+
+# host declaration
+host test1 {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ fixed-address 10.5.5.1, 10.10.10.10;
+}
+
+# group declaration
+group "foobar" {
+ default-lease-time 1800;
+ option domain-search "example.com", "example.org";
+ next-server 192.168.0.1;
+
+ # host declarations
+ host test2 {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address 10.5.5.2;
+ option domain-name "example.com";
+ option domain-search "example.com", "com";
+ }
+
+ host test3 {
+ hardware fddi 00:07:0E:36:48:19;
+ fixed-address 10.10.10.1;
+ default-lease-time 3600;
+ }
+}
+
+subnet 10.10.10.0 netmask 255.255.255.224 { }
diff --git a/keama/tests/grouphost4.out b/keama/tests/grouphost4.out
new file mode 100644
index 00000000..2027c536
--- /dev/null
+++ b/keama/tests/grouphost4.out
@@ -0,0 +1,78 @@
+{
+ # group and host declarations config
+ # subnet4 declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ],
+ "reservations": [
+ # host declaration
+ {
+ "hostname": "test1",
+ "hw-address": "00:0b:fd:32:e6:fa",
+ "ip-address": "10.5.5.1"
+// "extra-ip-addresses": [
+// "10.10.10.10"
+// ]
+ },
+ # host declarations
+ {
+ "hostname": "test2",
+ "hw-address": "00:07:0e:36:48:19",
+ "ip-address": "10.5.5.2",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-name",
+ "code": 15,
+ "data": "example.com"
+ },
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"com\"",
+ "data": "example.com, com"
+ }
+ ],
+ "next-server": "192.168.0.1"
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "subnet": "10.10.10.0/27",
+ "reservations": [
+// {
+// "hostname": "test3",
+// "hw-address": "fddi 00:07:0e:36:48:19",
+// "ip-address": "10.10.10.1",
+// /// default-valid-lifetime in unsupported scope
+// "valid-lifetime": 3600,
+// "option-data": [
+// {
+// "space": "dhcp4",
+// "name": "domain-search",
+// "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+// "data": "example.com, example.org"
+// }
+// ],
+// "next-server": "192.168.0.1"
+// }
+ ]
+ }
+ ],
+ "host-reservation-identifiers": [
+ "hw-address"
+ ]
+ }
+}
diff --git a/keama/tests/groupinclass.err b/keama/tests/groupinclass.err
new file mode 100644
index 00000000..dbc320a4
--- /dev/null
+++ b/keama/tests/groupinclass.err
@@ -0,0 +1,10 @@
+# group declaration inside class declaration config
+
+# host declaration
+class "foobar" {
+ # can't put a group declaration here
+ group "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/groupinclass.msg b/keama/tests/groupinclass.msg
new file mode 100644
index 00000000..ee72c674
--- /dev/null
+++ b/keama/tests/groupinclass.msg
@@ -0,0 +1 @@
+groupinclass.err line 6: group declarations not allowed here.
diff --git a/keama/tests/groupsubnet4.in4 b/keama/tests/groupsubnet4.in4
new file mode 100644
index 00000000..a7a199dc
--- /dev/null
+++ b/keama/tests/groupsubnet4.in4
@@ -0,0 +1,24 @@
+# Group with DHCPv4 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1200;
+
+# group declaration
+group foobar {
+ # option
+ option domain-search "example.com", "example.org";
+
+ # parameters
+ default-lease-time 3600;
+ ignore-client-uids false;
+
+ # DHCPv4 subnet declaration
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ # at least one pool is required
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+ interface "en0";
+ default-lease-time 1800;
+ }
+}
diff --git a/keama/tests/groupsubnet4.out b/keama/tests/groupsubnet4.out
new file mode 100644
index 00000000..f2db5f85
--- /dev/null
+++ b/keama/tests/groupsubnet4.out
@@ -0,0 +1,38 @@
+{
+ # Group with DHCPv4 subnet declaration config
+ # parameter which will be changed in subnet
+ "Dhcp4": {
+ "valid-lifetime": 1200,
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ "subnet4": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # at least one pool is required
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ],
+ "interface": "en0",
+ "valid-lifetime": 1800,
+ "option-data": [
+ # option
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "match-client-id": true
+ }
+ ]
+ }
+}
diff --git a/keama/tests/groupsubnet6.in6 b/keama/tests/groupsubnet6.in6
new file mode 100644
index 00000000..90277618
--- /dev/null
+++ b/keama/tests/groupsubnet6.in6
@@ -0,0 +1,24 @@
+# Group with DHCPv6 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1200;
+
+# group declaration
+group foobar {
+ # option
+ option dhcp6.domain-search "example.com", "example.org";
+
+ # parameters
+ default-lease-time 3600;
+
+ # DHCPv4 subnet declaration
+ subnet6 2001::/64 {
+ # at least one pool is required
+ pool6 {
+ range6 2001::100 2001::200;
+ }
+ interface "en0";
+ default-lease-time 1800;
+ option dhcp6.lq-relay-data 2001::1 "foobar";
+ }
+}
diff --git a/keama/tests/groupsubnet6.out b/keama/tests/groupsubnet6.out
new file mode 100644
index 00000000..63d5794e
--- /dev/null
+++ b/keama/tests/groupsubnet6.out
@@ -0,0 +1,44 @@
+{
+ # Group with DHCPv6 subnet declaration config
+ # parameter which will be changed in subnet
+ "Dhcp6": {
+ "valid-lifetime": 1200,
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ "subnet6": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ # at least one pool is required
+ {
+ "pool": "2001::100 - 2001::200"
+ }
+ ],
+ "interface": "en0",
+ "valid-lifetime": 1800,
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "lq-relay-data",
+ "code": 47,
+// "original-data": "2001::1 \"foobar\"",
+ "data": "2001::1, 666f6f626172"
+ },
+ # option
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/groupsubnetif.err4 b/keama/tests/groupsubnetif.err4
new file mode 100644
index 00000000..9a407b11
--- /dev/null
+++ b/keama/tests/groupsubnetif.err4
@@ -0,0 +1,19 @@
+# bad (interface unlnown in this cope) group declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1200;
+
+# group declaration
+group foobar {
+ # interface
+ interface "foo";
+
+ # DHCPv4 subnet declaration
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ # at least one pool is required
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+ interface "bar";
+ }
+}
diff --git a/keama/tests/groupsubnetif.msg b/keama/tests/groupsubnetif.msg
new file mode 100644
index 00000000..1828b932
--- /dev/null
+++ b/keama/tests/groupsubnetif.msg
@@ -0,0 +1 @@
+groupsubnetif.err4 line 7: expecting a parameter or declaration
diff --git a/keama/tests/hardware2dx4.in4 b/keama/tests/hardware2dx4.in4
new file mode 100644
index 00000000..73046612
--- /dev/null
+++ b/keama/tests/hardware2dx4.in4
@@ -0,0 +1,13 @@
+# simplified hardware data expression
+
+# hardware type class
+class "ethernet" {
+ match if substring(hardware, 0, 1) = encode-int(1, 8);
+}
+
+# ethernet address superclass
+class "ethernet-address" {
+ match substring(hardware, 1, 6);
+}
+
+subclass "ethernet-address" 00:0B:FD:32:E6:FA { }
diff --git a/keama/tests/hardware2dx4.out b/keama/tests/hardware2dx4.out
new file mode 100644
index 00000000..77c3f533
--- /dev/null
+++ b/keama/tests/hardware2dx4.out
@@ -0,0 +1,25 @@
+{
+ # simplified hardware data expression
+ # hardware type class
+ "Dhcp4": {
+ "client-classes": [
+ {
+ "name": "ethernet",
+ /// from: match if (substring(hardware, 0, 1)) = (encode-int(1, 8))
+ "test": "substring(pkt4.htype,-1,all) == '\u0001'"
+ },
+ # ethernet address superclass
+ /// match: substring(hardware, 1, 6)
+ {
+ "name": "ethernet-address"
+ },
+ /// subclass selector 0x0x000bfd32e6fa
+ {
+ "name": "sub#ethernet-address#0",
+ /// from: match substring(hardware, 1, 6)
+ /// data: 0x000bfd32e6fa
+ "test": "substring(pkt4.mac,0,6) == 0x000bfd32e6fa"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/hardwaredx4.in4 b/keama/tests/hardwaredx4.in4
new file mode 100644
index 00000000..46160776
--- /dev/null
+++ b/keama/tests/hardwaredx4.in4
@@ -0,0 +1,16 @@
+# hardware data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# pretty standard hardware superclass
+class "byhw" {
+ match hardware;
+}
+
+subclass "byhw" 01:00:07:0E:36:48:19 {
+ option host-name "test1";
+}
+
+# raw
+option host-name = binary-to-ascii(16, 8, "-", hardware);
diff --git a/keama/tests/hardwaredx4.out b/keama/tests/hardwaredx4.out
new file mode 100644
index 00000000..a3f13938
--- /dev/null
+++ b/keama/tests/hardwaredx4.out
@@ -0,0 +1,55 @@
+{
+ # hardware data expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # pretty standard hardware superclass
+ /// match: hardware
+ {
+ "name": "byhw"
+ },
+ /// subclass selector 0x0x0100070e364819
+ {
+ "name": "sub#byhw#0",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "host-name",
+ "code": 12,
+ "data": "test1"
+ }
+ ],
+ /// from: match hardware
+ /// data: 0x0100070e364819
+ "test": "concat(substring(pkt4.htype,-1,all), pkt4.mac) == 0x0100070e364819"
+ }
+ ],
+ "option-data": [
+// # raw
+// {
+// "space": "dhcp4",
+// "name": "host-name",
+// "code": 12,
+// "csv-format": false,
+// "expression": {
+// "binary-to-ascii": {
+// "base": 16,
+// "width": 8,
+// "separator": "-",
+// "buffer": {
+// "concat": {
+// "left": {
+// "hw-type": null
+// },
+// "right": {
+// "hw-address": null
+// }
+// }
+// }
+// }
+// }
+// }
+ ]
+ }
+}
diff --git a/keama/tests/hardwareinroot.err b/keama/tests/hardwareinroot.err
new file mode 100644
index 00000000..22902f20
--- /dev/null
+++ b/keama/tests/hardwareinroot.err
@@ -0,0 +1,5 @@
+# hardware declaration in root config
+
+# hardware declaration must be in a host declaration
+hardware ethernet 00:0B:FD:32:E6:FA;
+
diff --git a/keama/tests/hardwareinroot.msg b/keama/tests/hardwareinroot.msg
new file mode 100644
index 00000000..6cf018d0
--- /dev/null
+++ b/keama/tests/hardwareinroot.msg
@@ -0,0 +1 @@
+hardwareinroot.err line 4: hardware address parameter not allowed here.
diff --git a/keama/tests/host6.notyet b/keama/tests/host6.notyet
new file mode 100644
index 00000000..daff911e
--- /dev/null
+++ b/keama/tests/host6.notyet
@@ -0,0 +1,20 @@
+# DHCPv6 host declaration config
+
+# authoritative is mandatory
+authoritative;
+
+# subnet declaration
+subnet6 2001::/64 {
+ range6 2001::100 2001::200;
+}
+
+# host declarations
+host test1 {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address6 2001::1, 2001::10;
+}
+
+host test2 {
+ hardware fddi 00:07:0E:36:48:19;
+ fixed-prefix6 2001:0:0:1::/64;
+}
diff --git a/keama/tests/hostidentifier4.inl b/keama/tests/hostidentifier4.inl
new file mode 100644
index 00000000..9e50ddd3
--- /dev/null
+++ b/keama/tests/hostidentifier4.inl
@@ -0,0 +1,30 @@
+# host declaration with flexible identifiers config
+
+# subnet4 declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ range 10.5.5.5 10.5.5.10;
+}
+
+# option definition
+
+option my-id code 250 = text;
+
+# host declarations
+host test1 {
+ host-identifier option my-id test1;
+ option domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ fixed-address 10.5.5.1, 10.10.10.10;
+}
+
+host test2 {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address 10.5.5.2;
+}
+
+host test3 {
+ hardware fddi 00:07:0E:36:48:19;
+ fixed-address 10.10.10.1;
+}
+
+subnet 10.10.10.0 netmask 255.255.255.224 { }
diff --git a/keama/tests/hostidentifier4.outl b/keama/tests/hostidentifier4.outl
new file mode 100644
index 00000000..24af2ac5
--- /dev/null
+++ b/keama/tests/hostidentifier4.outl
@@ -0,0 +1,78 @@
+{
+ # host declaration with flexible identifiers config
+ # subnet4 declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "subnet": "10.10.10.0/27"
+ }
+ ],
+ "option-def": [
+ # option definition
+ {
+ "space": "dhcp4",
+ "name": "my-id",
+ "code": 250,
+ "type": "string"
+ }
+ ],
+ "host-reservation-identifiers": [
+ "flex-id",
+ "hw-address"
+ ],
+ /// The flexible host identifier is a premium feature
+ "hooks-libraries": [
+ {
+ "library": "/path/libdhcp_flex_id.so",
+ "parameters": {
+ "identifier-expression": "option[250].hex"
+ }
+ }
+ ],
+ "reservation-mode": "global",
+ "reservations": [
+ # host declarations
+ {
+ "hostname": "test1",
+ "flex-id": "'test1'",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+// /// default-valid-lifetime in unsupported scope
+// "valid-lifetime": 1800,
+ "ip-address": "10.5.5.1"
+// "extra-ip-addresses": [
+// "10.10.10.10"
+// ]
+ },
+ {
+ "hostname": "test2",
+ "hw-address": "00:07:0e:36:48:19",
+ "ip-address": "10.5.5.2"
+ }
+// {
+// "hostname": "test3",
+// "hw-address": "fddi 00:07:0e:36:48:19",
+// "ip-address": "10.10.10.1"
+// }
+ ]
+ }
+}
diff --git a/keama/tests/hostinclass.err b/keama/tests/hostinclass.err
new file mode 100644
index 00000000..ac5075ee
--- /dev/null
+++ b/keama/tests/hostinclass.err
@@ -0,0 +1,10 @@
+# host declaration inside class declaration config
+
+# class declaration
+class "foobar" {
+ # can't put a host declaration here
+ host illegal {
+ hardware ethernet 00:07:0E:36:48:19;
+ }
+}
+
diff --git a/keama/tests/hostinclass.msg b/keama/tests/hostinclass.msg
new file mode 100644
index 00000000..004446ba
--- /dev/null
+++ b/keama/tests/hostinclass.msg
@@ -0,0 +1 @@
+hostinclass.err line 6: host declarations not allowed here.
diff --git a/keama/tests/hostinhost.err b/keama/tests/hostinhost.err
new file mode 100644
index 00000000..8da7d425
--- /dev/null
+++ b/keama/tests/hostinhost.err
@@ -0,0 +1,11 @@
+# host declaration inside host declaration config
+
+# host declaration
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ # can't put another host declaration here
+ host illegal {
+ hardware ethernet 00:07:0E:36:48:19;
+ }
+}
+
diff --git a/keama/tests/hostinhost.msg b/keama/tests/hostinhost.msg
new file mode 100644
index 00000000..3ddfbd7a
--- /dev/null
+++ b/keama/tests/hostinhost.msg
@@ -0,0 +1 @@
+hostinhost.err line 7: host declarations not allowed here.
diff --git a/keama/tests/hostname4.in4 b/keama/tests/hostname4.in4
new file mode 100644
index 00000000..8e2db319
--- /dev/null
+++ b/keama/tests/hostname4.in4
@@ -0,0 +1,18 @@
+# host name config
+
+# subnet4 declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ range 10.5.5.5 10.5.5.10;
+}
+
+# host declaration
+host test1 {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ fixed-address 10.5.5.1;
+}
+
+# host declaration using a longer name
+host test2.example.com {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address 10.5.5.2;
+}
diff --git a/keama/tests/hostname4.out b/keama/tests/hostname4.out
new file mode 100644
index 00000000..d6973a48
--- /dev/null
+++ b/keama/tests/hostname4.out
@@ -0,0 +1,37 @@
+{
+ # host name config
+ # subnet4 declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ }
+ ],
+ "host-reservation-identifiers": [
+ "hw-address"
+ ],
+ "reservation-mode": "global",
+ "reservations": [
+ # host declaration
+ {
+ "hostname": "test1",
+ "hw-address": "00:0b:fd:32:e6:fa",
+ "ip-address": "10.5.5.1"
+ },
+ # host declaration using a longer name
+ {
+ "hostname": "test2.example.com",
+ "hw-address": "00:07:0e:36:48:19",
+ "ip-address": "10.5.5.2"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/hostnum.errF b/keama/tests/hostnum.errF
new file mode 100644
index 00000000..4c89dc27
--- /dev/null
+++ b/keama/tests/hostnum.errF
@@ -0,0 +1,7 @@
+# numeric with address hostname config
+
+host 1901.fr {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address 1901.fr;
+}
+
diff --git a/keama/tests/hostnum.msg b/keama/tests/hostnum.msg
new file mode 100644
index 00000000..cc734bc0
--- /dev/null
+++ b/keama/tests/hostnum.msg
@@ -0,0 +1 @@
+hostnum.errF line 5: expected IPv4 address. got hostname 1901.fr
diff --git a/keama/tests/hostuid4.inn b/keama/tests/hostuid4.inn
new file mode 100644
index 00000000..867fa8b4
--- /dev/null
+++ b/keama/tests/hostuid4.inn
@@ -0,0 +1,29 @@
+# host declaration with client-identfiers config
+
+# subnet4 declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ range 10.5.5.5 10.5.5.10;
+}
+
+# recommended when using dhcp-client-identifier options
+ignore-client-uids false;
+
+# host declarations
+host test1 {
+ uid 01:02:03:04:05:0a:0b:0c:0d:0e:0f;
+ option domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ fixed-address 10.5.5.1, 10.10.10.10;
+}
+
+host test2 {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address 10.5.5.2;
+}
+
+host test3 {
+ hardware fddi 00:07:0E:36:48:19;
+ fixed-address 10.10.10.1;
+}
+
+subnet 10.10.10.0 netmask 255.255.255.224 { }
diff --git a/keama/tests/hostuid4.out b/keama/tests/hostuid4.out
new file mode 100644
index 00000000..ad3f3e36
--- /dev/null
+++ b/keama/tests/hostuid4.out
@@ -0,0 +1,62 @@
+{
+ # host declaration with client-identfiers config
+ # subnet4 declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ],
+ "reservations": [
+ # host declarations
+ {
+ "hostname": "test1",
+ "client-id": "01:02:03:04:05:0a:0b:0c:0d:0e:0f",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+// /// default-valid-lifetime in unsupported scope
+// "valid-lifetime": 1800,
+ "ip-address": "10.5.5.1"
+// "extra-ip-addresses": [
+// "10.10.10.10"
+// ]
+ },
+ {
+ "hostname": "test2",
+ "hw-address": "00:07:0e:36:48:19",
+ "ip-address": "10.5.5.2"
+ }
+ ]
+ },
+ {
+ "id": 2,
+ "subnet": "10.10.10.0/27",
+ "reservations": [
+// {
+// "hostname": "test3",
+// "hw-address": "fddi 00:07:0e:36:48:19",
+// "ip-address": "10.10.10.1"
+// }
+ ]
+ }
+ ],
+ "match-client-id": true,
+ "host-reservation-identifiers": [
+ "client-id",
+ "hw-address"
+ ]
+ }
+}
diff --git a/keama/tests/ifxsc4.in4 b/keama/tests/ifxsc4.in4
new file mode 100644
index 00000000..b3a59bcc
--- /dev/null
+++ b/keama/tests/ifxsc4.in4
@@ -0,0 +1,17 @@
+# if executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# if statement
+# first true is not recognized even as a boolean expression
+if true {
+ option ip-forwarding true;
+}
+
+# another
+if ( option user-class = "accounting" ) {
+ option boot-size 100000;
+} elsif option user-class = "engineering" {
+ option domain-name "example.com";
+}
diff --git a/keama/tests/ifxsc4.out b/keama/tests/ifxsc4.out
new file mode 100644
index 00000000..ca086910
--- /dev/null
+++ b/keama/tests/ifxsc4.out
@@ -0,0 +1,79 @@
+{
+ # if executable statement construct
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// # if statement
+// # first true is not recognized even as a boolean expression
+// "statement": {
+// "if": {
+// "condition": {
+// "variable-reference": "true"
+// },
+// "then": [
+// {
+// "option": {
+// "space": "dhcp4",
+// "name": "ip-forwarding",
+// "code": 19,
+// "data": "true"
+// }
+// }
+// ]
+// }
+// }
+// # another
+// "statement": {
+// "if": {
+// "condition": {
+// "equal": {
+// "left": {
+// "option": {
+// "universe": "dhcp",
+// "name": "user-class",
+// "code": 77
+// }
+// },
+// "right": "accounting"
+// }
+// },
+// "then": [
+// {
+// "option": {
+// "space": "dhcp4",
+// "name": "boot-size",
+// "code": 13,
+// "data": "100000"
+// }
+// }
+// ],
+// "else": {
+// "if": {
+// "condition": {
+// "equal": {
+// "left": {
+// "option": {
+// "universe": "dhcp",
+// "name": "user-class",
+// "code": 77
+// }
+// },
+// "right": "engineering"
+// }
+// },
+// "then": [
+// {
+// "option": {
+// "space": "dhcp4",
+// "name": "domain-name",
+// "code": 15,
+// "data": "example.com"
+// }
+// }
+// ]
+// }
+// }
+// }
+// }
+ }
+}
diff --git a/keama/tests/ipaddr6.in6 b/keama/tests/ipaddr6.in6
new file mode 100644
index 00000000..60c27175
--- /dev/null
+++ b/keama/tests/ipaddr6.in6
@@ -0,0 +1,3 @@
+# IPv6 addresses config
+
+option dhcp6.name-servers 2001::, 200a::0bF, 2001::192.168.0.1;
diff --git a/keama/tests/ipaddr6.out b/keama/tests/ipaddr6.out
new file mode 100644
index 00000000..b2118c61
--- /dev/null
+++ b/keama/tests/ipaddr6.out
@@ -0,0 +1,14 @@
+{
+ # IPv6 addresses config
+ "Dhcp6": {
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "dns-servers",
+ "code": 23,
+// "original-data": "2001::, 200a::0bF, 2001::192.168.0.1",
+ "data": "2001::, 200a::bf, 2001::c0a8:1"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/ipaddrhost4.in4 b/keama/tests/ipaddrhost4.in4
new file mode 100644
index 00000000..1c43f81b
--- /dev/null
+++ b/keama/tests/ipaddrhost4.in4
@@ -0,0 +1,8 @@
+# hostname config
+
+host test1 {
+ hardware ethernet 00:07:0E:36:48:19;
+ fixed-address www.isc.org;
+}
+
+subnet 149.20.64.0 netmask 255.255.255.128 { }
diff --git a/keama/tests/ipaddrhost4.out b/keama/tests/ipaddrhost4.out
new file mode 100644
index 00000000..22a36643
--- /dev/null
+++ b/keama/tests/ipaddrhost4.out
@@ -0,0 +1,24 @@
+{
+ # hostname config
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "host-reservation-identifiers": [
+ "hw-address"
+ ],
+ "reservation-mode": "global",
+ "reservations": [
+ {
+ "hostname": "test1",
+ "hw-address": "00:07:0e:36:48:19",
+ "ip-address": "151.101.122.217"
+ }
+ ],
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "149.20.64.0/25"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/ipaddrs4.notyet4 b/keama/tests/ipaddrs4.notyet4
new file mode 100644
index 00000000..6430e0f9
--- /dev/null
+++ b/keama/tests/ipaddrs4.notyet4
@@ -0,0 +1,11 @@
+# hostname config
+
+# authoritative is mandatory
+authoritative;
+
+host test1 {
+ hardware ethernet 00:07:0E:36:48:19;
+ # www.apple.fr has multiple addresses but they are not returned
+ # in a stable order
+ fixed-address www.apple.fr;
+}
diff --git a/keama/tests/lifetime4.ind b/keama/tests/lifetime4.ind
new file mode 100644
index 00000000..4e8594ab
--- /dev/null
+++ b/keama/tests/lifetime4.ind
@@ -0,0 +1,5 @@
+# DHCPv4 use ISC DHCP default lifetimes but not when configured.
+
+min-lease-time 3600;
+default-lease-time 7200;
+max-lease-time 14400;
diff --git a/keama/tests/lifetime4.out b/keama/tests/lifetime4.out
new file mode 100644
index 00000000..e5360af0
--- /dev/null
+++ b/keama/tests/lifetime4.out
@@ -0,0 +1,8 @@
+{
+ # DHCPv4 use ISC DHCP default lifetimes but not when configured.
+ "Dhcp4": {
+ "min-valid-lifetime": 3600,
+ "valid-lifetime": 7200,
+ "max-valid-lifetime": 14400
+ }
+}
diff --git a/keama/tests/lifetime6.inD b/keama/tests/lifetime6.inD
new file mode 100644
index 00000000..4e8594ab
--- /dev/null
+++ b/keama/tests/lifetime6.inD
@@ -0,0 +1,5 @@
+# DHCPv4 use ISC DHCP default lifetimes but not when configured.
+
+min-lease-time 3600;
+default-lease-time 7200;
+max-lease-time 14400;
diff --git a/keama/tests/lifetime6.out b/keama/tests/lifetime6.out
new file mode 100644
index 00000000..5cc28de0
--- /dev/null
+++ b/keama/tests/lifetime6.out
@@ -0,0 +1,8 @@
+{
+ # DHCPv4 use ISC DHCP default lifetimes but not when configured.
+ "Dhcp6": {
+ "min-valid-lifetime": 3600,
+ "valid-lifetime": 7200,
+ "max-valid-lifetime": 14400
+ }
+}
diff --git a/keama/tests/lifetimedef4.ind b/keama/tests/lifetimedef4.ind
new file mode 100644
index 00000000..881edf57
--- /dev/null
+++ b/keama/tests/lifetimedef4.ind
@@ -0,0 +1 @@
+# DHCPv4 use ISC DHCP default lifetimes
diff --git a/keama/tests/lifetimedef4.out b/keama/tests/lifetimedef4.out
new file mode 100644
index 00000000..1e194bf4
--- /dev/null
+++ b/keama/tests/lifetimedef4.out
@@ -0,0 +1,11 @@
+{
+ # DHCPv4 use ISC DHCP default lifetimes
+ "Dhcp4": {
+ /// Use ISC DHCP default lifetime
+ "valid-lifetime": 43200,
+ /// Use ISC DHCP min lifetime
+ "min-valid-lifetime": 300,
+ /// Use ISC DHCP max lifetime
+ "max-valid-lifetime": 86400
+ }
+}
diff --git a/keama/tests/lifetimedef6.inD b/keama/tests/lifetimedef6.inD
new file mode 100644
index 00000000..59718e40
--- /dev/null
+++ b/keama/tests/lifetimedef6.inD
@@ -0,0 +1 @@
+# DHCPv6 use ISC DHCP default lifetimes
diff --git a/keama/tests/lifetimedef6.out b/keama/tests/lifetimedef6.out
new file mode 100644
index 00000000..274997d1
--- /dev/null
+++ b/keama/tests/lifetimedef6.out
@@ -0,0 +1,11 @@
+{
+ # DHCPv6 use ISC DHCP default lifetimes
+ "Dhcp6": {
+ /// Use ISC DHCP default lifetime
+ "valid-lifetime": 43200,
+ /// Use ISC DHCP min lifetime
+ "min-valid-lifetime": 300,
+ /// Use ISC DHCP max lifetime
+ "max-valid-lifetime": 86400
+ }
+}
diff --git a/keama/tests/listarray.err b/keama/tests/listarray.err
new file mode 100644
index 00000000..14082605
--- /dev/null
+++ b/keama/tests/listarray.err
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+
+# arrays of domain lists are forbidden
+option foobar.array-list code 1 = array of domain-list;
diff --git a/keama/tests/listarray.msg b/keama/tests/listarray.msg
new file mode 100644
index 00000000..2a363531
--- /dev/null
+++ b/keama/tests/listarray.msg
@@ -0,0 +1 @@
+listarray.err line 7: arrays of text strings not yet supported.
diff --git a/keama/tests/minimal4.in4 b/keama/tests/minimal4.in4
new file mode 100644
index 00000000..cfcc1282
--- /dev/null
+++ b/keama/tests/minimal4.in4
@@ -0,0 +1,4 @@
+# DHCPv4 minimal config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
diff --git a/keama/tests/minimal4.out b/keama/tests/minimal4.out
new file mode 100644
index 00000000..e256972c
--- /dev/null
+++ b/keama/tests/minimal4.out
@@ -0,0 +1,7 @@
+{
+ # DHCPv4 minimal config
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+ }
+}
diff --git a/keama/tests/minimal6.in6 b/keama/tests/minimal6.in6
new file mode 100644
index 00000000..57c83491
--- /dev/null
+++ b/keama/tests/minimal6.in6
@@ -0,0 +1,4 @@
+# DHCPv6 minimal config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
diff --git a/keama/tests/minimal6.out b/keama/tests/minimal6.out
new file mode 100644
index 00000000..c07d37fd
--- /dev/null
+++ b/keama/tests/minimal6.out
@@ -0,0 +1,7 @@
+{
+ # DHCPv6 minimal config
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800
+ }
+}
diff --git a/keama/tests/mixedarray.err b/keama/tests/mixedarray.err
new file mode 100644
index 00000000..507aca78
--- /dev/null
+++ b/keama/tests/mixedarray.err
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+
+# not uniform arrays are forbidden
+option foobar.nestarray code 1 = { array of { unsigned integer 32 } };
diff --git a/keama/tests/mixedarray.msg b/keama/tests/mixedarray.msg
new file mode 100644
index 00000000..c409ad01
--- /dev/null
+++ b/keama/tests/mixedarray.msg
@@ -0,0 +1 @@
+mixedarray.err line 7: only uniform array inside record.
diff --git a/keama/tests/nestarray.err b/keama/tests/nestarray.err
new file mode 100644
index 00000000..58f16bbe
--- /dev/null
+++ b/keama/tests/nestarray.err
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+
+# nested arrays are forbidden
+option foobar.nestarray code 1 = array of array of unsigned integer 32;
diff --git a/keama/tests/nestarray.msg b/keama/tests/nestarray.msg
new file mode 100644
index 00000000..92335fad
--- /dev/null
+++ b/keama/tests/nestarray.msg
@@ -0,0 +1 @@
+nestarray.err line 7: no nested arrays.
diff --git a/keama/tests/noauth4.in4 b/keama/tests/noauth4.in4
new file mode 100644
index 00000000..e2fce24c
--- /dev/null
+++ b/keama/tests/noauth4.in4
@@ -0,0 +1,7 @@
+# no(t) authoritative config
+
+# authoritative is no longer mandatory
+#authoritative;
+
+subnet 10.5.5.0 netmask 255.255.255.224 { }
+
diff --git a/keama/tests/noauth4.out b/keama/tests/noauth4.out
new file mode 100644
index 00000000..8dac17f7
--- /dev/null
+++ b/keama/tests/noauth4.out
@@ -0,0 +1,15 @@
+{
+ # no(t) authoritative config
+ # authoritative is no longer mandatory
+ #authoritative;
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/noauth6.in6 b/keama/tests/noauth6.in6
new file mode 100644
index 00000000..42894e91
--- /dev/null
+++ b/keama/tests/noauth6.in6
@@ -0,0 +1,6 @@
+# no(t) authoritative config
+
+# authoritative is no longer mandatory
+#authoritative;
+
+subnet6 2001::/64 { }
diff --git a/keama/tests/noauth6.out b/keama/tests/noauth6.out
new file mode 100644
index 00000000..93f8429e
--- /dev/null
+++ b/keama/tests/noauth6.out
@@ -0,0 +1,15 @@
+{
+ # no(t) authoritative config
+ # authoritative is no longer mandatory
+ #authoritative;
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/noclass.err b/keama/tests/noclass.err
new file mode 100644
index 00000000..8aed2e34
--- /dev/null
+++ b/keama/tests/noclass.err
@@ -0,0 +1,7 @@
+# orphan subclass declaration config
+
+# class declaration
+subclass "foobar" "abcd {
+ default-lease-time 1800;
+}
+
diff --git a/keama/tests/noclass.msg b/keama/tests/noclass.msg
new file mode 100644
index 00000000..ab8719e3
--- /dev/null
+++ b/keama/tests/noclass.msg
@@ -0,0 +1 @@
+noclass.err line 4: no class named foobar
diff --git a/keama/tests/noinclude.err b/keama/tests/noinclude.err
new file mode 100644
index 00000000..f39f388b
--- /dev/null
+++ b/keama/tests/noinclude.err
@@ -0,0 +1,3 @@
+# no file include config
+
+include "do-not-exist";
diff --git a/keama/tests/noinclude.msg b/keama/tests/noinclude.msg
new file mode 100644
index 00000000..91b2284b
--- /dev/null
+++ b/keama/tests/noinclude.msg
@@ -0,0 +1 @@
+noinclude.err line 3: Can't open do-not-exist: No such file or directory
diff --git a/keama/tests/nosubclass.err b/keama/tests/nosubclass.err
new file mode 100644
index 00000000..cf421259
--- /dev/null
+++ b/keama/tests/nosubclass.err
@@ -0,0 +1,11 @@
+# bad (missing selector) subclass declaration config
+
+# superclass declaration
+class "foobar" {
+ match substring(option vendor-class-identifier, 0, 3);
+}
+
+# subclass declaration
+subclass "foobar" {
+ default-lease-time 1800;
+}
diff --git a/keama/tests/nosubclass.msg b/keama/tests/nosubclass.msg
new file mode 100644
index 00000000..762e440f
--- /dev/null
+++ b/keama/tests/nosubclass.msg
@@ -0,0 +1 @@
+nosubclass.err line 9: Expecting string or hex list.
diff --git a/keama/tests/nosuperclass.err b/keama/tests/nosuperclass.err
new file mode 100644
index 00000000..5d2e329f
--- /dev/null
+++ b/keama/tests/nosuperclass.err
@@ -0,0 +1,11 @@
+# bas superclass subclass declaration config
+
+# class (but not superclass) declaration
+class "foobar" {
+ match if substring(option vendor-class-identifier, 0, 3) = "APC";
+}
+
+# subclass declaration
+subclass "foobar" "abcd {
+ default-lease-time 1800;
+}
diff --git a/keama/tests/nosuperclass.msg b/keama/tests/nosuperclass.msg
new file mode 100644
index 00000000..ec448cad
--- /dev/null
+++ b/keama/tests/nosuperclass.msg
@@ -0,0 +1 @@
+nosuperclass.err line 9: found class name foobar but it is not a suitable superclass
diff --git a/keama/tests/notbx4.in4 b/keama/tests/notbx4.in4
new file mode 100644
index 00000000..6248b8c6
--- /dev/null
+++ b/keama/tests/notbx4.in4
@@ -0,0 +1,12 @@
+# not boolean expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# use not in a reductible match if
+class "reductible" {
+ match if not (option host-name = "www.example.com");
+}
+
+# if test is a boolean too
+if not check "foo" { add "bar"; }
diff --git a/keama/tests/notbx4.out b/keama/tests/notbx4.out
new file mode 100644
index 00000000..186cdfff
--- /dev/null
+++ b/keama/tests/notbx4.out
@@ -0,0 +1,30 @@
+{
+ # not boolean expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # use not in a reductible match if
+ {
+ "name": "reductible",
+ /// from: match if not (option dhcp.host-name) = 'www.example.com'
+ "test": "not (option[12].hex == 'www.example.com')"
+ }
+ ]
+// # if test is a boolean too
+// "statement": {
+// "if": {
+// "condition": {
+// "not": {
+// "check": "foo"
+// }
+// },
+// "then": [
+// {
+// "add-class": "bar"
+// }
+// ]
+// }
+// }
+ }
+}
diff --git a/keama/tests/notnotbx4.in4 b/keama/tests/notnotbx4.in4
new file mode 100644
index 00000000..e9d98800
--- /dev/null
+++ b/keama/tests/notnotbx4.in4
@@ -0,0 +1,15 @@
+# double not boolean expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# use double not in a reductible match if
+class "reductible" {
+ match if not (not ((option host-name = "www.example.com") or
+ (option host-name = "www.example.org")));
+}
+
+# use not with !=
+class "other" {
+ match if not (option host-name != "www.example.com");
+}
diff --git a/keama/tests/notnotbx4.out b/keama/tests/notnotbx4.out
new file mode 100644
index 00000000..ae1878cc
--- /dev/null
+++ b/keama/tests/notnotbx4.out
@@ -0,0 +1,21 @@
+{
+ # double not boolean expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # use double not in a reductible match if
+ {
+ "name": "reductible",
+ /// from: match if not not ((option dhcp.host-name) = 'www.example.com') or ((option dhcp.host-name) = 'www.example.org')
+ "test": "(option[12].hex == 'www.example.com') or (option[12].hex == 'www.example.org')"
+ },
+ # use not with !=
+ {
+ "name": "other",
+ /// from: match if not (option dhcp.host-name) != 'www.example.com'
+ "test": "option[12].hex == 'www.example.com'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/nxdomainnx6.in6 b/keama/tests/nxdomainnx6.in6
new file mode 100644
index 00000000..f2a2e0f5
--- /dev/null
+++ b/keama/tests/nxdomainnx6.in6
@@ -0,0 +1,12 @@
+# nxdomain numeric expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# reduce literals
+class "literal" {
+ match if substring(option dhcp6.interface-id, 0, nxdomain % 128) = ab:cd;
+}
+
+# raw
+option dhcp6.interface-id = encode-int(nxdomain + bound, 32);
diff --git a/keama/tests/nxdomainnx6.out b/keama/tests/nxdomainnx6.out
new file mode 100644
index 00000000..c90552e4
--- /dev/null
+++ b/keama/tests/nxdomainnx6.out
@@ -0,0 +1,28 @@
+{
+ # nxdomain numeric expression
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # reduce literals
+ {
+ "name": "literal",
+ /// from: match if (substring(option dhcp6.interface-id, 0, 393231 % 128)) = 0xabcd
+ "test": "substring(option[18].hex,0,15) == 0xabcd"
+ }
+ ],
+ "option-data": [
+ # raw
+ {
+ "space": "dhcp6",
+ "name": "interface-id",
+ "code": 18,
+ "csv-format": false,
+// /// constant DHCP_R_NXDOMAIN(393231)
+// /// constant S_BOUND(5)
+// "original-data": "\u0000\u0006\u0000\u0014",
+ "data": "00060014"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/onxsc4.in4 b/keama/tests/onxsc4.in4
new file mode 100644
index 00000000..f62b720c
--- /dev/null
+++ b/keama/tests/onxsc4.in4
@@ -0,0 +1,12 @@
+# on executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# empty on statement
+on expiry;
+
+# another one
+on commit or release {
+ execute ("myscript", packet(5, 2));
+}
diff --git a/keama/tests/onxsc4.out b/keama/tests/onxsc4.out
new file mode 100644
index 00000000..95134a52
--- /dev/null
+++ b/keama/tests/onxsc4.out
@@ -0,0 +1,34 @@
+{
+ # on executable statement construct
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// # empty on statement
+// "statement": {
+// "on": {
+// "condition": "expiry"
+// }
+// }
+// # another one
+// "statement": {
+// "on": {
+// "condition": "commit or release",
+// "body": [
+// {
+// "execute": {
+// "command": "myscript",
+// "arguments": [
+// {
+// "packet": {
+// "offset": 5,
+// "length": 2
+// }
+// }
+// ]
+// }
+// }
+// ]
+// }
+// }
+ }
+}
diff --git a/keama/tests/optdatagrouppool4.in4 b/keama/tests/optdatagrouppool4.in4
new file mode 100644
index 00000000..999abea2
--- /dev/null
+++ b/keama/tests/optdatagrouppool4.in4
@@ -0,0 +1,18 @@
+# embedded option-data in DHCPv4 pool config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # pool declaration
+ pool {
+ # avoid empty pool
+ range 10.5.5.5 10.5.5.10;
+ # for a silly reason option-data is not allowed in DHCPv4 pools
+ # try to fool this rule using a group
+ group fool {
+ option domain-search "example.com", "example.org";
+ }
+ }
+}
diff --git a/keama/tests/optdatagrouppool4.out b/keama/tests/optdatagrouppool4.out
new file mode 100644
index 00000000..4fb102d3
--- /dev/null
+++ b/keama/tests/optdatagrouppool4.out
@@ -0,0 +1,23 @@
+{
+ # embedded option-data in DHCPv4 pool config
+ # empty configs are not accepted by Kea
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "subnet4": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondata4.in4 b/keama/tests/optiondata4.in4
new file mode 100644
index 00000000..6c5ab639
--- /dev/null
+++ b/keama/tests/optiondata4.in4
@@ -0,0 +1,48 @@
+# option data config
+
+# options
+option space foobar;
+
+option ip-forwarding on;
+
+option foobar.fmt-b-si8 code 3 = signed integer 8;
+option foobar.fmt-b-si8 -100;
+
+option default-ip-ttl 20;
+
+option foobar.fmt-s-si16 code 6 = signed integer 16;
+option foobar.fmt-s-si16 -1000;
+
+option boot-size 16000;
+
+option time-offset -1200;
+
+option path-mtu-aging-timeout 86400;
+
+option swap-server 10.5.5.1;
+
+option foobar.fmt-6 code 12 = ip6-address;
+option foobar.fmt-6 2001::1;
+
+option foobar.fmt-d code 13 = domain-name;
+# Silly, d aka domain-name are without quotes, D aka domain-list are with
+option foobar.fmt-d www.example.com;
+
+option bcms-controller-names "foo.bar", "www.no-where.biz";
+
+option domain-search "example.com", "example.org";
+
+option tftp-server-name "my-server";
+
+option dhcp-client-identifier 01:02:aa:bb;
+
+option foobar.fmt-Z code 18 = zerolen;
+option foobar.fmt-Z;
+
+option foobar.fmt-Ba code 50 = array of unsigned integer 8;
+option dhcp-parameter-request-list 1, 2, 3;
+
+option foobar.fmt-fB code 100 = { boolean, unsigned integer 8 };
+option foobar.fmt-fB off 66;
+
+option routers 10.5.5.1, 10.5.5.2, 10.5.5.3;
diff --git a/keama/tests/optiondata4.out b/keama/tests/optiondata4.out
new file mode 100644
index 00000000..eca745d9
--- /dev/null
+++ b/keama/tests/optiondata4.out
@@ -0,0 +1,173 @@
+{
+ # option data config
+ # options
+ "Dhcp4": {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "ip-forwarding",
+ "code": 19,
+// "original-data": "on",
+ /// canonized booleans to lowercase true or false
+ "data": "true"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-si8",
+ "code": 3,
+ "data": "-100"
+ },
+ {
+ "space": "dhcp4",
+ "name": "default-ip-ttl",
+ "code": 23,
+ "data": "20"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-si16",
+ "code": 6,
+ "data": "-1000"
+ },
+ {
+ "space": "dhcp4",
+ "name": "boot-size",
+ "code": 13,
+ "data": "16000"
+ },
+ {
+ "space": "dhcp4",
+ "name": "time-offset",
+ "code": 2,
+ "data": "-1200"
+ },
+ {
+ "space": "dhcp4",
+ "name": "path-mtu-aging-timeout",
+ "code": 24,
+ "data": "86400"
+ },
+ {
+ "space": "dhcp4",
+ "name": "swap-server",
+ "code": 16,
+ "data": "10.5.5.1"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-6",
+ "code": 12,
+ "data": "2001::1"
+ },
+ # Silly, d aka domain-name are without quotes, D aka domain-list are with
+ {
+ "space": "foobar",
+ "name": "fmt-d",
+ "code": 13,
+ "data": "www.example.com"
+ },
+ {
+ "space": "dhcp4",
+ "name": "bcms-controller-names",
+ "code": 88,
+// "original-data": "\"foo.bar\", \"www.no-where.biz\"",
+ "data": "foo.bar, www.no-where.biz"
+ },
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ },
+ {
+ "space": "dhcp4",
+ "name": "tftp-server-name",
+ "code": 66,
+ "data": "my-server"
+ },
+ {
+ "space": "dhcp4",
+ "name": "dhcp-client-identifier",
+ "code": 61,
+// "original-data": "01:02:aa:bb",
+ "csv-format": false,
+ "data": "0102aabb"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Z",
+ "code": 18,
+ "data": ""
+ },
+ /// Possible PRL hack
+ /// Consider setting "always-send" to true when setting data for relevant options, cf Kea #250
+ {
+ "space": "dhcp4",
+ "name": "dhcp-parameter-request-list",
+ "code": 55,
+ "data": "1, 2, 3"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-fB",
+ "code": 100,
+// "original-data": "off 66",
+ /// canonized booleans to lowercase true or false
+ "data": "false, 66"
+ },
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "10.5.5.1, 10.5.5.2, 10.5.5.3"
+ }
+ ],
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "fmt-b-si8",
+ "code": 3,
+ "type": "int8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-si16",
+ "code": 6,
+ "type": "int16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-6",
+ "code": 12,
+ "type": "ipv6-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-d",
+ "code": 13,
+ "type": "fqdn"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Z",
+ "code": 18,
+ "type": "empty"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Ba",
+ "code": 50,
+ "array": true,
+ "type": "uint8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-fB",
+ "code": 100,
+ "record-types": "boolean, uint8",
+ "type": "record"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondata6.in6 b/keama/tests/optiondata6.in6
new file mode 100644
index 00000000..5af5b87b
--- /dev/null
+++ b/keama/tests/optiondata6.in6
@@ -0,0 +1,49 @@
+# option data config
+
+# options
+option space foobar;
+
+option foobar.fmt-f code 1 = boolean;
+option foobar.fmt-f true;
+
+option foobar.fmt-b-i8 code 2 = integer 8;
+option foobar.fmt-b-i8 -10;
+
+option dhcp6.preference 20;
+
+option foobar.fmt-s-i16 code 5 = integer 16;
+option foobar.fmt-s-i16 -10000;
+
+option foobar.fmt-S-ui16 code 7 = unsigned integer 16;
+option foobar.fmt-S-ui16 36000;
+
+option foobar.fmt-l-i32 code 8 = integer 32;
+option foobar.fmt-l-i32 -86400;
+
+option dhcp6.clt-time 604800;
+
+option foobar.fmt-I code 11 = ip-address;
+option foobar.fmt-I 10.5.5.1;
+
+option foobar.fmt-6 code 12 = ip6-address;
+option dhcp6.unicast 2001::1;
+
+option foobar.fmt-d code 13 = domain-name;
+# Silly, d aka domain-name are without quotes, D aka domain-list are with
+option foobar.fmt-d www.example.com;
+
+option dhcp6.domain-search "example.com", "example.org";
+
+option dhcp6.bootfile-url "http://nowhere/";
+
+option dhcp6.geoconf-civic de:ad:be:ef;
+
+option dhcp6.rapid-commit;
+
+option foobar.fmt-Ba code 50 = array of unsigned integer 8;
+option foobar.fmt-Ba 1, 2, 3;
+
+option foobar.fmt-fB code 100 = { boolean, unsigned integer 8 };
+option foobar.fmt-fB false 66;
+
+option dhcp6.name-servers 2a01:e00::2, 2a01:e00::2;
diff --git a/keama/tests/optiondata6.out b/keama/tests/optiondata6.out
new file mode 100644
index 00000000..b01ba36b
--- /dev/null
+++ b/keama/tests/optiondata6.out
@@ -0,0 +1,178 @@
+{
+ # option data config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "fmt-f",
+ "code": 1,
+ "type": "boolean"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-i8",
+ "code": 2,
+ "type": "int8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-i16",
+ "code": 5,
+ "type": "int16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-S-ui16",
+ "code": 7,
+ "type": "uint16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-l-i32",
+ "code": 8,
+ "type": "int32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-I",
+ "code": 11,
+ "type": "ipv4-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-6",
+ "code": 12,
+ "type": "ipv6-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-d",
+ "code": 13,
+ "type": "fqdn"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Ba",
+ "code": 50,
+ "array": true,
+ "type": "uint8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-fB",
+ "code": 100,
+ "record-types": "boolean, uint8",
+ "type": "record"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "foobar",
+ "name": "fmt-f",
+ "code": 1,
+ "data": "true"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-i8",
+ "code": 2,
+ "data": "-10"
+ },
+ {
+ "space": "dhcp6",
+ "name": "preference",
+ "code": 7,
+ "data": "20"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-i16",
+ "code": 5,
+ "data": "-10000"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-S-ui16",
+ "code": 7,
+ "data": "36000"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-l-i32",
+ "code": 8,
+ "data": "-86400"
+ },
+ {
+ "space": "dhcp6",
+ "name": "clt-time",
+ "code": 46,
+ "data": "604800"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-I",
+ "code": 11,
+ "data": "10.5.5.1"
+ },
+ {
+ "space": "dhcp6",
+ "name": "unicast",
+ "code": 12,
+ "data": "2001::1"
+ },
+ # Silly, d aka domain-name are without quotes, D aka domain-list are with
+ {
+ "space": "foobar",
+ "name": "fmt-d",
+ "code": 13,
+ "data": "www.example.com"
+ },
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ },
+ {
+ "space": "dhcp6",
+ "name": "bootfile-url",
+ "code": 59,
+ "data": "http://nowhere/"
+ },
+ {
+ "space": "dhcp6",
+ "name": "geoconf-civic",
+ "code": 36,
+// "original-data": "de:ad:be:ef",
+ "csv-format": false,
+ "data": "deadbeef"
+ },
+ {
+ "space": "dhcp6",
+ "name": "rapid-commit",
+ "code": 14,
+ "data": ""
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Ba",
+ "code": 50,
+ "data": "1, 2, 3"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-fB",
+ "code": 100,
+ "data": "false, 66"
+ },
+ {
+ "space": "dhcp6",
+ "name": "dns-servers",
+ "code": 23,
+ "data": "2a01:e00::2, 2a01:e00::2"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondatapool4.in4 b/keama/tests/optiondatapool4.in4
new file mode 100644
index 00000000..58751b01
--- /dev/null
+++ b/keama/tests/optiondatapool4.in4
@@ -0,0 +1,12 @@
+# option-data in DHCPv4 pool config
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # pool declaration
+ pool {
+ # avoid empty pool
+ range 10.5.5.5 10.5.5.10;
+ # fixed now
+ option domain-search "example.com", "example.org";
+ }
+}
diff --git a/keama/tests/optiondatapool4.out b/keama/tests/optiondatapool4.out
new file mode 100644
index 00000000..1d3ee427
--- /dev/null
+++ b/keama/tests/optiondatapool4.out
@@ -0,0 +1,31 @@
+{
+ # option-data in DHCPv4 pool config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "10.5.5.5 - 10.5.5.10",
+ "option-data": [
+ # fixed now
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondatapool6.in6 b/keama/tests/optiondatapool6.in6
new file mode 100644
index 00000000..d09ebaf9
--- /dev/null
+++ b/keama/tests/optiondatapool6.in6
@@ -0,0 +1,13 @@
+# option-data in DHCPv6 pool config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # pool declaration
+ pool6 {
+ # avoid empty pool
+ range6 2001::100 2001::200;
+ # for a silly reason option-data is not allowed in DHCPv4 pools
+ # but allowed in DHCPv6 pools
+ option dhcp6.domain-search "example.com", "example.org";
+ }
+}
diff --git a/keama/tests/optiondatapool6.out b/keama/tests/optiondatapool6.out
new file mode 100644
index 00000000..48f722d4
--- /dev/null
+++ b/keama/tests/optiondatapool6.out
@@ -0,0 +1,32 @@
+{
+ # option-data in DHCPv6 pool config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "2001::100 - 2001::200",
+ "option-data": [
+ # for a silly reason option-data is not allowed in DHCPv4 pools
+ # but allowed in DHCPv6 pools
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondecl4.in4 b/keama/tests/optiondecl4.in4
new file mode 100644
index 00000000..4be48838
--- /dev/null
+++ b/keama/tests/optiondecl4.in4
@@ -0,0 +1,27 @@
+# option definition config
+
+# options
+option space foobar;
+
+option foobar.fmt-f code 1 = boolean;
+option foobar.fmt-b-i8 code 2 = integer 8;
+option foobar.fmt-b-si8 code 3 = signed integer 8;
+option foobar.fmt-B-ui8 code 4 = unsigned integer 8;
+option foobar.fmt-s-i16 code 5 = integer 16;
+option foobar.fmt-s-si16 code 6 = signed integer 16;
+option foobar.fmt-S-ui16 code 7 = unsigned integer 16;
+option foobar.fmt-l-i32 code 8 = integer 32;
+option foobar.fmt-l-si32 code 9 = signed integer 32;
+option foobar.fmt-L-ui32 code 10 = unsigned integer 32;
+option foobar.fmt-I code 11 = ip-address;
+option foobar.fmt-6 code 12 = ip6-address;
+option foobar.fmt-d code 13 = domain-name;
+option foobar.fmt-D-list code 14 = domain-list;
+option foobar.fmt-Dc code 15 = domain-list compressed;
+option foobar.fmt-t code 16 = text;
+option foobar.fmt-X code 17 = string;
+option foobar.fmt-Z code 18 = zerolen;
+
+option foobar.fmt-Ba code 50 = array of unsigned integer 8;
+option foobar.fmt-fB code 100 = { boolean, unsigned integer 8 };
+option foobar.fmt-Ia code 150 = { unsigned integer 32, array of boolean };
diff --git a/keama/tests/optiondecl4.out b/keama/tests/optiondecl4.out
new file mode 100644
index 00000000..f74aa32f
--- /dev/null
+++ b/keama/tests/optiondecl4.out
@@ -0,0 +1,143 @@
+{
+ # option definition config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "fmt-f",
+ "code": 1,
+ "type": "boolean"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-i8",
+ "code": 2,
+ "type": "int8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-si8",
+ "code": 3,
+ "type": "int8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-B-ui8",
+ "code": 4,
+ "type": "uint8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-i16",
+ "code": 5,
+ "type": "int16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-si16",
+ "code": 6,
+ "type": "int16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-S-ui16",
+ "code": 7,
+ "type": "uint16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-l-i32",
+ "code": 8,
+ "type": "int32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-l-si32",
+ "code": 9,
+ "type": "int32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-L-ui32",
+ "code": 10,
+ "type": "uint32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-I",
+ "code": 11,
+ "type": "ipv4-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-6",
+ "code": 12,
+ "type": "ipv6-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-d",
+ "code": 13,
+ "type": "fqdn"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-D-list",
+ "code": 14,
+ "array": true,
+ "type": "fqdn"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Dc",
+ "code": 15,
+ "array": true,
+ "type": "fqdn"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-t",
+ "code": 16,
+ "type": "string"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-X",
+ "code": 17,
+ "type": "string"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Z",
+ "code": 18,
+ "type": "empty"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Ba",
+ "code": 50,
+ "array": true,
+ "type": "uint8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-fB",
+ "code": 100,
+ "record-types": "boolean, uint8",
+ "type": "record"
+ },
+ /// unsupported array inside a record
+ {
+ "space": "foobar",
+ "name": "fmt-Ia",
+ "code": 150,
+// "array": true,
+// "definition": "{ uint32, array of boolean}",
+ /// Option definition is not compatible with Kea
+ /// Fallback to full binary
+ "type": "binary"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondecl6.in6 b/keama/tests/optiondecl6.in6
new file mode 100644
index 00000000..37662c0d
--- /dev/null
+++ b/keama/tests/optiondecl6.in6
@@ -0,0 +1,27 @@
+# option definition config
+
+# options
+option space foobar;
+
+option foobar.fmt-f code 1 = boolean;
+option foobar.fmt-b-i8 code 2 = integer 8;
+option foobar.fmt-b-si8 code 3 = signed integer 8;
+option foobar.fmt-B-ui8 code 4 = unsigned integer 8;
+option foobar.fmt-s-i16 code 5 = integer 16;
+option foobar.fmt-s-si16 code 6 = signed integer 16;
+option foobar.fmt-S-ui16 code 7 = unsigned integer 16;
+option foobar.fmt-l-i32 code 8 = integer 32;
+option foobar.fmt-l-si32 code 9 = signed integer 32;
+option foobar.fmt-L-ui32 code 10 = unsigned integer 32;
+option foobar.fmt-I code 11 = ip-address;
+option foobar.fmt-6 code 12 = ip6-address;
+option foobar.fmt-d code 13 = domain-name;
+option foobar.fmt-D-list code 14 = domain-list;
+#option foobar.fmt-Dc code 15 = domain-list compressed;
+option foobar.fmt-t code 16 = text;
+option foobar.fmt-X code 17 = string;
+option foobar.fmt-Z code 18 = zerolen;
+
+option foobar.fmt-Ba code 50 = array of unsigned integer 8;
+option foobar.fmt-fB code 100 = { boolean, unsigned integer 8 };
+option foobar.fmt-Lfa code 150 = { unsigned integer 32, array of boolean };
diff --git a/keama/tests/optiondecl6.out b/keama/tests/optiondecl6.out
new file mode 100644
index 00000000..d4cf828b
--- /dev/null
+++ b/keama/tests/optiondecl6.out
@@ -0,0 +1,137 @@
+{
+ # option definition config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "fmt-f",
+ "code": 1,
+ "type": "boolean"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-i8",
+ "code": 2,
+ "type": "int8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-b-si8",
+ "code": 3,
+ "type": "int8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-B-ui8",
+ "code": 4,
+ "type": "uint8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-i16",
+ "code": 5,
+ "type": "int16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-s-si16",
+ "code": 6,
+ "type": "int16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-S-ui16",
+ "code": 7,
+ "type": "uint16"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-l-i32",
+ "code": 8,
+ "type": "int32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-l-si32",
+ "code": 9,
+ "type": "int32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-L-ui32",
+ "code": 10,
+ "type": "uint32"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-I",
+ "code": 11,
+ "type": "ipv4-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-6",
+ "code": 12,
+ "type": "ipv6-address"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-d",
+ "code": 13,
+ "type": "fqdn"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-D-list",
+ "code": 14,
+ "array": true,
+ "type": "fqdn"
+ },
+ #option foobar.fmt-Dc code 15 = domain-list compressed;
+ {
+ "space": "foobar",
+ "name": "fmt-t",
+ "code": 16,
+ "type": "string"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-X",
+ "code": 17,
+ "type": "string"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Z",
+ "code": 18,
+ "type": "empty"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-Ba",
+ "code": 50,
+ "array": true,
+ "type": "uint8"
+ },
+ {
+ "space": "foobar",
+ "name": "fmt-fB",
+ "code": 100,
+ "record-types": "boolean, uint8",
+ "type": "record"
+ },
+ /// unsupported array inside a record
+ {
+ "space": "foobar",
+ "name": "fmt-Lfa",
+ "code": 150,
+// "array": true,
+// "definition": "{ uint32, array of boolean}",
+ /// Option definition is not compatible with Kea
+ /// Fallback to full binary
+ "type": "binary"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optiondeclBat4.in4 b/keama/tests/optiondeclBat4.in4
new file mode 100644
index 00000000..0901a14f
--- /dev/null
+++ b/keama/tests/optiondeclBat4.in4
@@ -0,0 +1,6 @@
+# bad Bat (non terminal array) option declaration
+
+option space foobar;
+option foobar.fmt-Bat code 1 = { array of unsigned integer 8, text };
+
+
diff --git a/keama/tests/optiondeclBat4.out b/keama/tests/optiondeclBat4.out
new file mode 100644
index 00000000..e671dcfa
--- /dev/null
+++ b/keama/tests/optiondeclBat4.out
@@ -0,0 +1,18 @@
+{
+ # bad Bat (non terminal array) option declaration
+ "Dhcp4": {
+ "option-def": [
+ /// unsupported array inside a record
+ {
+ "space": "foobar",
+ "name": "fmt-Bat",
+ "code": 1,
+// "array": true,
+// "definition": "{ array of uint8, string}",
+ /// Option definition is not compatible with Kea
+ /// Fallback to full binary
+ "type": "binary"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optionencap4.in4 b/keama/tests/optionencap4.in4
new file mode 100644
index 00000000..f5dddfdb
--- /dev/null
+++ b/keama/tests/optionencap4.in4
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+option space xyz;
+
+option foobar.encap code 1 = encapsulate xyz;
diff --git a/keama/tests/optionencap4.out b/keama/tests/optionencap4.out
new file mode 100644
index 00000000..ee59fc42
--- /dev/null
+++ b/keama/tests/optionencap4.out
@@ -0,0 +1,15 @@
+{
+ # option definition config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "encap",
+ "code": 1,
+ "type": "empty",
+ "encapsulate": "xyz"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optionencap6.in6 b/keama/tests/optionencap6.in6
new file mode 100644
index 00000000..f5dddfdb
--- /dev/null
+++ b/keama/tests/optionencap6.in6
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+option space xyz;
+
+option foobar.encap code 1 = encapsulate xyz;
diff --git a/keama/tests/optionencap6.out b/keama/tests/optionencap6.out
new file mode 100644
index 00000000..733fc714
--- /dev/null
+++ b/keama/tests/optionencap6.out
@@ -0,0 +1,15 @@
+{
+ # option definition config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "encap",
+ "code": 1,
+ "type": "empty",
+ "encapsulate": "xyz"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optionexpr4.in4 b/keama/tests/optionexpr4.in4
new file mode 100644
index 00000000..bc0889dd
--- /dev/null
+++ b/keama/tests/optionexpr4.in4
@@ -0,0 +1,16 @@
+# option data expressions
+
+# options
+option mytext code 250 = text;
+option mytext = substring("foobar", 1, 3);
+
+option mydata code 251 = string;
+option mydata = concat("\b", "\125\126");
+
+option mydata2 code 252 = string;
+option mydata2 = aa:bb:cc;
+
+# not yet
+option mydata3 code 253 = string;
+option mydata3 = concat(aa, bb, cc);
+
diff --git a/keama/tests/optionexpr4.out b/keama/tests/optionexpr4.out
new file mode 100644
index 00000000..3582b3d7
--- /dev/null
+++ b/keama/tests/optionexpr4.out
@@ -0,0 +1,81 @@
+{
+ # option data expressions
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "mytext",
+ "code": 250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "mydata",
+ "code": 251,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "mydata2",
+ "code": 252,
+ "type": "string"
+ },
+ # not yet
+ {
+ "space": "dhcp4",
+ "name": "mydata3",
+ "code": 253,
+ "type": "string"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "mytext",
+ "code": 250,
+ "csv-format": false,
+// "original-data": "oob",
+ "data": "6f6f62"
+ },
+ {
+ "space": "dhcp4",
+ "name": "mydata",
+ "code": 251,
+ "csv-format": false,
+// "original-data": "\bUV",
+ "data": "085556"
+ },
+ {
+ "space": "dhcp4",
+ "name": "mydata2",
+ "code": 252,
+ "csv-format": false,
+ "data": "aabbcc"
+ }
+// {
+// "space": "dhcp4",
+// "name": "mydata3",
+// "code": 253,
+// "csv-format": false,
+// "expression": {
+// "concat": {
+// "left": {
+// "const-data": "0xaa"
+// },
+// "right": {
+// "concat": {
+// "left": {
+// "const-data": "0xbb"
+// },
+// "right": {
+// "const-data": "0xcc"
+// }
+// }
+// }
+// }
+// }
+// }
+ ]
+ }
+}
diff --git a/keama/tests/optionspace4.in4 b/keama/tests/optionspace4.in4
new file mode 100644
index 00000000..fa87b6a5
--- /dev/null
+++ b/keama/tests/optionspace4.in4
@@ -0,0 +1,15 @@
+# group and class declaration config
+
+# option spaces
+option space foobar;
+
+option space foo code width 1 length width 1;
+
+option space bar code width 4 length width 4;
+
+option space full code width 2 length width 2 hash size 111;
+
+option foobar.test code 1 = text;
+
+option foo.test code 1 = text;
+
diff --git a/keama/tests/optionspace4.out b/keama/tests/optionspace4.out
new file mode 100644
index 00000000..53482692
--- /dev/null
+++ b/keama/tests/optionspace4.out
@@ -0,0 +1,34 @@
+{
+ # group and class declaration config
+ # option spaces
+ "Dhcp4": {
+// "option-space": {
+// "name": "bar",
+// /// Only code width 1 is supported
+// "code-width": 4,
+// /// Only length width 1 is supported
+// "length-width": 4
+// },
+// "option-space": {
+// "name": "full",
+// /// Only code width 1 is supported
+// "code-width": 2,
+// /// Only length width 1 is supported
+// "length-width": 2
+// },
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "test",
+ "code": 1,
+ "type": "string"
+ },
+ {
+ "space": "foo",
+ "name": "test",
+ "code": 1,
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optionspace6.in6 b/keama/tests/optionspace6.in6
new file mode 100644
index 00000000..a94a665f
--- /dev/null
+++ b/keama/tests/optionspace6.in6
@@ -0,0 +1,15 @@
+# group and class declaration config
+
+# option spaces
+option space foobar;
+
+option space foo code width 2 length width 2;
+
+option space bar code width 4 length width 4;
+
+option space full code width 1 length width 1 hash size 111;
+
+option foobar.test code 1 = text;
+
+option foo.test code 1 = text;
+
diff --git a/keama/tests/optionspace6.out b/keama/tests/optionspace6.out
new file mode 100644
index 00000000..fdc9ea72
--- /dev/null
+++ b/keama/tests/optionspace6.out
@@ -0,0 +1,34 @@
+{
+ # group and class declaration config
+ # option spaces
+ "Dhcp6": {
+// "option-space": {
+// "name": "bar",
+// /// Only code width 2 is supported
+// "code-width": 4,
+// /// Only length width 2 is supported
+// "length-width": 4
+// },
+// "option-space": {
+// "name": "full",
+// /// Only code width 2 is supported
+// "code-width": 1,
+// /// Only length width 2 is supported
+// "length-width": 1
+// },
+ "option-def": [
+ {
+ "space": "foobar",
+ "name": "test",
+ "code": 1,
+ "type": "string"
+ },
+ {
+ "space": "foo",
+ "name": "test",
+ "code": 1,
+ "type": "string"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optionvendor4.in4 b/keama/tests/optionvendor4.in4
new file mode 100644
index 00000000..49be45d7
--- /dev/null
+++ b/keama/tests/optionvendor4.in4
@@ -0,0 +1,8 @@
+# group and class declaration config
+
+# vendor option space
+option space foobar;
+
+option vendor.foobar code 12345 = encapsulate foobar;
+option foobar.test code 1 = text;
+option foobar.test "a test";
diff --git a/keama/tests/optionvendor4.out b/keama/tests/optionvendor4.out
new file mode 100644
index 00000000..80a9a5e8
--- /dev/null
+++ b/keama/tests/optionvendor4.out
@@ -0,0 +1,28 @@
+{
+ # group and class declaration config
+ # vendor option space
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "vendor-12345",
+ "name": "test",
+ "code": 1,
+ "type": "string"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "vivso-suboptions",
+ "code": 125,
+ "data": "12345"
+ },
+ {
+ "space": "vendor-12345",
+ "name": "test",
+ "code": 1,
+ "data": "a test"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/optionvendor6.in6 b/keama/tests/optionvendor6.in6
new file mode 100644
index 00000000..9a1a3757
--- /dev/null
+++ b/keama/tests/optionvendor6.in6
@@ -0,0 +1,8 @@
+# group and class declaration config
+
+# vendor option space
+option space foobar;
+
+option vsio.foobar code 12345 = encapsulate foobar;
+option foobar.test code 1 = text;
+option foobar.test "a test";
diff --git a/keama/tests/optionvendor6.out b/keama/tests/optionvendor6.out
new file mode 100644
index 00000000..8e163978
--- /dev/null
+++ b/keama/tests/optionvendor6.out
@@ -0,0 +1,28 @@
+{
+ # group and class declaration config
+ # vendor option space
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "vendor-12345",
+ "name": "test",
+ "code": 1,
+ "type": "string"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "vendor-opts",
+ "code": 17,
+ "data": "12345"
+ },
+ {
+ "space": "vendor-12345",
+ "name": "test",
+ "code": 1,
+ "data": "a test"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/orphan4.inn b/keama/tests/orphan4.inn
new file mode 100644
index 00000000..85f95639
--- /dev/null
+++ b/keama/tests/orphan4.inn
@@ -0,0 +1,10 @@
+# DHCPv4 orphan reservation config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# orphan reservation
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ option ip-forwarding off;
+}
diff --git a/keama/tests/orphan4.out b/keama/tests/orphan4.out
new file mode 100644
index 00000000..c0146767
--- /dev/null
+++ b/keama/tests/orphan4.out
@@ -0,0 +1,30 @@
+{
+ # DHCPv4 orphan reservation config
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "host-reservation-identifiers": [
+ "hw-address"
+ ]
+// /// Orphan reservations
+// /// Kea reservations are per subnet
+// /// Reference Kea #231
+// "reservations": [
+// # orphan reservation
+// {
+// "hostname": "foobar",
+// "hw-address": "00:0b:fd:32:e6:fa",
+// "option-data": [
+// {
+// "space": "dhcp4",
+// "name": "ip-forwarding",
+// "code": 19,
+// "original-data": "off",
+// /// canonized booleans to lowercase true or false
+// "data": "false"
+// }
+// ]
+// }
+// ]
+ }
+}
diff --git a/keama/tests/orphan6.inN b/keama/tests/orphan6.inN
new file mode 100644
index 00000000..e85368f2
--- /dev/null
+++ b/keama/tests/orphan6.inN
@@ -0,0 +1,10 @@
+# DHCPv6 orphan reservation config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# orphan reservation
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ option dhcp6.name-servers 2a01:e00::2, 2a01:e00::1;
+}
diff --git a/keama/tests/orphan6.out b/keama/tests/orphan6.out
new file mode 100644
index 00000000..0c0b8114
--- /dev/null
+++ b/keama/tests/orphan6.out
@@ -0,0 +1,28 @@
+{
+ # DHCPv6 orphan reservation config
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "host-reservation-identifiers": [
+ "hw-address"
+ ]
+// /// Orphan reservations
+// /// Kea reservations are per subnet
+// /// Reference Kea #231
+// "reservations": [
+// # orphan reservation
+// {
+// "hostname": "foobar",
+// "hw-address": "00:0b:fd:32:e6:fa",
+// "option-data": [
+// {
+// "space": "dhcp6",
+// "name": "dns-servers",
+// "code": 23,
+// "data": "2a01:e00::2, 2a01:e00::1"
+// }
+// ]
+// }
+// ]
+ }
+}
diff --git a/keama/tests/packetdx4.notyet b/keama/tests/packetdx4.notyet
new file mode 100644
index 00000000..03f3237d
--- /dev/null
+++ b/keama/tests/packetdx4.notyet
@@ -0,0 +1,20 @@
+# packet data expression
+# Kea has no raw packet extractor in libeval
+
+# authoritative is mandatory
+authoritative;
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# pretty standard hardware superclass extracting the Ethernet address directly
+class "byhw" {
+ match packet(28, 6);
+}
+
+subclass "byhw" 00:07:0E:36:48:19 {
+ option host-name "test1";
+}
+
+# raw
+option host-name = binary-to-ascii(16, 8, "-", packet(28, 6));
diff --git a/keama/tests/permitauth4.in4 b/keama/tests/permitauth4.in4
new file mode 100644
index 00000000..b9663fd2
--- /dev/null
+++ b/keama/tests/permitauth4.in4
@@ -0,0 +1,15 @@
+# DHCPv4 permit authenticated client config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # pool declaration
+ pool {
+ # avoid empty pool
+ range 10.5.5.5 10.5.5.10;
+ # call get_permit
+ allow authenticated clients;
+ }
+}
diff --git a/keama/tests/permitauth4.out b/keama/tests/permitauth4.out
new file mode 100644
index 00000000..0f938566
--- /dev/null
+++ b/keama/tests/permitauth4.out
@@ -0,0 +1,33 @@
+{
+ # DHCPv4 permit authenticated client config
+ # empty configs are not accepted by Kea
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "subnet4": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "10.5.5.5 - 10.5.5.10",
+ /// From:
+ /// allow authenticated clients
+ /// [un]authenticated-clients is not supported by ISC DHCP and Kea
+ "client-class": "gen#!ALL#"
+ }
+ ]
+ }
+ ],
+ "client-classes": [
+ {
+ "name": "gen#!ALL#",
+ "test": "not member('ALL')"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/permitauth6.in6 b/keama/tests/permitauth6.in6
new file mode 100644
index 00000000..ce0a25aa
--- /dev/null
+++ b/keama/tests/permitauth6.in6
@@ -0,0 +1,15 @@
+# DHCPv6 permit authenticated client config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# subnet declaration
+subnet6 2001::/64 {
+ # pool declaration
+ pool6 {
+ # avoid empty pool
+ range6 2001::100 2001::200;
+ # call get_permit
+ deny unauthenticated clients;
+ }
+}
diff --git a/keama/tests/permitauth6.out b/keama/tests/permitauth6.out
new file mode 100644
index 00000000..f2013e77
--- /dev/null
+++ b/keama/tests/permitauth6.out
@@ -0,0 +1,33 @@
+{
+ # DHCPv6 permit authenticated client config
+ # empty configs are not accepted by Kea
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "subnet6": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "2001::100 - 2001::200",
+ /// From:
+ /// deny unauthenticated clients
+ /// [un]authenticated-clients is not supported by ISC DHCP and Kea
+ "client-class": "gen#_AND_#!ALL#"
+ }
+ ]
+ }
+ ],
+ "client-classes": [
+ {
+ "name": "gen#_AND_#!ALL#",
+ "test": "not member('ALL')"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/permitknown4.in4 b/keama/tests/permitknown4.in4
new file mode 100644
index 00000000..df15e11e
--- /dev/null
+++ b/keama/tests/permitknown4.in4
@@ -0,0 +1,15 @@
+# DHCPv4 permit known client config
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # pool declaration
+ pool {
+ # avoid empty pool
+ range 10.5.5.5 10.5.5.10;
+ # call get_permit
+ allow known clients;
+ }
+}
diff --git a/keama/tests/permitknown4.out b/keama/tests/permitknown4.out
new file mode 100644
index 00000000..1a27d5a9
--- /dev/null
+++ b/keama/tests/permitknown4.out
@@ -0,0 +1,26 @@
+{
+ # DHCPv4 permit known client config
+ # empty configs are not accepted by Kea
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "subnet4": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # pool declaration
+ {
+ # avoid empty pool
+ "pool": "10.5.5.5 - 10.5.5.10",
+ /// From:
+ /// allow known clients
+ "client-class": "KNOWN"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/pickdx6.in6 b/keama/tests/pickdx6.in6
new file mode 100644
index 00000000..ccfa48ce
--- /dev/null
+++ b/keama/tests/pickdx6.in6
@@ -0,0 +1,15 @@
+# pick-first-value data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# reduce literals
+class "literal" {
+ match if option dhcp6.client-data =
+ pick-first-value(substring("abcd",0,0),null,"foobar");
+}
+
+# null
+class "null" {
+ match if option dhcp6.client-data = pick(null);
+}
diff --git a/keama/tests/pickdx6.out b/keama/tests/pickdx6.out
new file mode 100644
index 00000000..d8de1130
--- /dev/null
+++ b/keama/tests/pickdx6.out
@@ -0,0 +1,21 @@
+{
+ # pick-first-value data expression
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # reduce literals
+ {
+ "name": "literal",
+ /// from: match if (option dhcp6.client-data) = (pick-first-value(substring('abcd', 0, 0), null, 'foobar'))
+ "test": "option[45].hex == 'foobar'"
+ },
+ # null
+ {
+ "name": "null",
+ /// from: match if (option dhcp6.client-data) = (pick-first-value(null))
+ "test": "option[45].hex == ''"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/pool4.in4 b/keama/tests/pool4.in4
new file mode 100644
index 00000000..0e156141
--- /dev/null
+++ b/keama/tests/pool4.in4
@@ -0,0 +1,11 @@
+# DHCPv4 pool config
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # pool declaration
+ pool {
+ option domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ range 10.5.5.5 10.5.5.10;
+ }
+}
diff --git a/keama/tests/pool4.out b/keama/tests/pool4.out
new file mode 100644
index 00000000..e0b6bee8
--- /dev/null
+++ b/keama/tests/pool4.out
@@ -0,0 +1,31 @@
+{
+ # DHCPv4 pool config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ /// default-valid-lifetime moved from an internal pool scope
+ "valid-lifetime": 1800,
+ "pools": [
+ # pool declaration
+ {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/pool42.in4 b/keama/tests/pool42.in4
new file mode 100644
index 00000000..7e7fea3f
--- /dev/null
+++ b/keama/tests/pool42.in4
@@ -0,0 +1,15 @@
+# DHCPv4 pool with 2 ranges config
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # pool declaration
+ pool {
+ option domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ range 10.5.5.5 10.5.5.10;
+ # add a second range
+ range 10.5.5.11 10.5.5.12;
+ }
+ # interface
+ interface "en0";
+}
diff --git a/keama/tests/pool42.out b/keama/tests/pool42.out
new file mode 100644
index 00000000..38a039b8
--- /dev/null
+++ b/keama/tests/pool42.out
@@ -0,0 +1,49 @@
+{
+ # DHCPv4 pool with 2 ranges config
+ # subnet declaration
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ /// default-valid-lifetime moved from an internal pool scope
+ "valid-lifetime": 1800,
+ "pools": [
+ # pool declaration
+ {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "pool": "10.5.5.5 - 10.5.5.10"
+ },
+ # pool declaration
+ {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ # add a second range
+ "pool": "10.5.5.11 - 10.5.5.12"
+ }
+ ],
+ "interface": "en0"
+ }
+ ],
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ }
+ }
+}
diff --git a/keama/tests/pool6.in6 b/keama/tests/pool6.in6
new file mode 100644
index 00000000..2cd2fa39
--- /dev/null
+++ b/keama/tests/pool6.in6
@@ -0,0 +1,11 @@
+# DHCPv6 pool config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # pool declaration
+ pool6 {
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ range6 2001::100 2001::200;
+ }
+}
diff --git a/keama/tests/pool6.out b/keama/tests/pool6.out
new file mode 100644
index 00000000..626610dc
--- /dev/null
+++ b/keama/tests/pool6.out
@@ -0,0 +1,31 @@
+{
+ # DHCPv6 pool config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ /// default-valid-lifetime moved from an internal pool scope
+ "valid-lifetime": 1800,
+ "pools": [
+ # pool declaration
+ {
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "pool": "2001::100 - 2001::200"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/pool6in4.err4 b/keama/tests/pool6in4.err4
new file mode 100644
index 00000000..44d19cf6
--- /dev/null
+++ b/keama/tests/pool6in4.err4
@@ -0,0 +1,13 @@
+# DHCPv6 pool declaration in DHCPv4 config
+
+# host declaration
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ default-lease-time 1800;
+}
+
+# There is a declaration so the error message is different
+
+# DHCPv6 pool declaration must be in DHCPv6 config
+range6 2001::/64;
+
diff --git a/keama/tests/pool6in4.msg b/keama/tests/pool6in4.msg
new file mode 100644
index 00000000..f6df706e
--- /dev/null
+++ b/keama/tests/pool6in4.msg
@@ -0,0 +1 @@
+pool6in4.err4 line 12: expecting a declaration
diff --git a/keama/tests/poolinroot4.err4 b/keama/tests/poolinroot4.err4
new file mode 100644
index 00000000..6caa6d47
--- /dev/null
+++ b/keama/tests/poolinroot4.err4
@@ -0,0 +1,7 @@
+# DHCPv4 pool declaration in root config
+
+# DHCPv4 pool declaration must be in a shared-network or subnet declaration
+pool {
+ range 204.152.185.135 204.152.185.185;
+}
+
diff --git a/keama/tests/poolinroot4.msg b/keama/tests/poolinroot4.msg
new file mode 100644
index 00000000..845744fd
--- /dev/null
+++ b/keama/tests/poolinroot4.msg
@@ -0,0 +1 @@
+poolinroot4.err4 line 4: pool declared outside of network
diff --git a/keama/tests/poolinroot6.err6 b/keama/tests/poolinroot6.err6
new file mode 100644
index 00000000..6605f086
--- /dev/null
+++ b/keama/tests/poolinroot6.err6
@@ -0,0 +1,7 @@
+# DHCPv6 pool declaration in root config
+
+# DHCPv6 pool declaration must be in a shared-network or subnet declaration
+pool6 {
+ range6 2001::/64;
+}
+
diff --git a/keama/tests/poolinroot6.msg b/keama/tests/poolinroot6.msg
new file mode 100644
index 00000000..5f48f13d
--- /dev/null
+++ b/keama/tests/poolinroot6.msg
@@ -0,0 +1 @@
+poolinroot6.err6 line 4: pool6 declared outside of network
diff --git a/keama/tests/preferred6.in6 b/keama/tests/preferred6.in6
new file mode 100644
index 00000000..9fd8519f
--- /dev/null
+++ b/keama/tests/preferred6.in6
@@ -0,0 +1,14 @@
+# preferred lifetime
+
+preferred-lifetime 1200;
+
+# embedded in pool
+subnet6 2001::/64 {
+ # silently overwritten
+ preferred-lifetime 1800;
+ pool6 {
+ preferred-lifetime 2400;
+ range6 2001::1000 2001::1fff;
+ }
+}
+
diff --git a/keama/tests/preferred6.out b/keama/tests/preferred6.out
new file mode 100644
index 00000000..88acf33d
--- /dev/null
+++ b/keama/tests/preferred6.out
@@ -0,0 +1,30 @@
+{
+ # preferred lifetime
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "preferred-lifetime": 1200,
+ "renew-timer": 600,
+ "rebind-timer": 960,
+ "subnet6": [
+ # embedded in pool
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "preferred-lifetime": 1800,
+ "renew-timer": 900,
+ "rebind-timer": 1440,
+// /// preferred-lifetime moved from an internal pool scope
+// /// Avoid to overwrite current value...
+// "preferred-lifetime": 2400,
+// "renew-timer": 1200,
+// "rebind-timer": 1920,
+ "pools": [
+ {
+ "pool": "2001::1000 - 2001::1fff"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/prefix0.err6 b/keama/tests/prefix0.err6
new file mode 100644
index 00000000..c10b6d15
--- /dev/null
+++ b/keama/tests/prefix0.err6
@@ -0,0 +1,9 @@
+# DHCPv6 (bad 128 bit length) prefix config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # range declaration
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: / 128;
+}
diff --git a/keama/tests/prefix0.msg b/keama/tests/prefix0.msg
new file mode 100644
index 00000000..73952817
--- /dev/null
+++ b/keama/tests/prefix0.msg
@@ -0,0 +1 @@
+prefix0.err6 line 8: networks have 0 to 128 bits (exclusive)
diff --git a/keama/tests/prefix128.err6 b/keama/tests/prefix128.err6
new file mode 100644
index 00000000..c10b6d15
--- /dev/null
+++ b/keama/tests/prefix128.err6
@@ -0,0 +1,9 @@
+# DHCPv6 (bad 128 bit length) prefix config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # range declaration
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: / 128;
+}
diff --git a/keama/tests/prefix128.msg b/keama/tests/prefix128.msg
new file mode 100644
index 00000000..ee874c74
--- /dev/null
+++ b/keama/tests/prefix128.msg
@@ -0,0 +1 @@
+prefix128.err6 line 8: networks have 0 to 128 bits (exclusive)
diff --git a/keama/tests/prefix6.in6 b/keama/tests/prefix6.in6
new file mode 100644
index 00000000..e5c01c90
--- /dev/null
+++ b/keama/tests/prefix6.in6
@@ -0,0 +1,9 @@
+# DHCPv6 prefix config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # range declaration
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: / 64;
+}
diff --git a/keama/tests/prefix6.out b/keama/tests/prefix6.out
new file mode 100644
index 00000000..e0fe3ea5
--- /dev/null
+++ b/keama/tests/prefix6.out
@@ -0,0 +1,32 @@
+{
+ # DHCPv6 prefix config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "option-data": [
+ # range declaration
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "pd-pools": [
+ {
+ "prefix": "2001:0:0:10::",
+ "delegated-len": 64,
+ "prefix-len": 60
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/prefix62.in6 b/keama/tests/prefix62.in6
new file mode 100644
index 00000000..408481a5
--- /dev/null
+++ b/keama/tests/prefix62.in6
@@ -0,0 +1,10 @@
+# DHCPv6 prefix config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # range declaration
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ prefix6 2001:0:0:1:: 2001:0:0:3:: / 64;
+ interface "en0";
+}
diff --git a/keama/tests/prefix62.out b/keama/tests/prefix62.out
new file mode 100644
index 00000000..0ce536a8
--- /dev/null
+++ b/keama/tests/prefix62.out
@@ -0,0 +1,36 @@
+{
+ # DHCPv6 prefix config
+ # subnet declaration
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "option-data": [
+ # range declaration
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "pd-pools": [
+// {
+// "prefix": "2001:0:0:1::",
+// "delegated-len": 64,
+// "prefix-highest": "2001:0:0:3::"
+// }
+ ],
+ "interface": "en0"
+ }
+ ],
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ }
+ }
+}
diff --git a/keama/tests/prefixinroot6.err6 b/keama/tests/prefixinroot6.err6
new file mode 100644
index 00000000..f1fd4a1e
--- /dev/null
+++ b/keama/tests/prefixinroot6.err6
@@ -0,0 +1,4 @@
+# DHCPv6 prefix declaration in root config
+
+# DHCPv6 prefix declaration must be in a subnet declaration
+prefix6 2001:: 2001:0:1:: / 64;
diff --git a/keama/tests/prefixinroot6.msg b/keama/tests/prefixinroot6.msg
new file mode 100644
index 00000000..8aa498f4
--- /dev/null
+++ b/keama/tests/prefixinroot6.msg
@@ -0,0 +1 @@
+prefixinroot6.err6 line 4: prefix6 declaration not allowed here.
diff --git a/keama/tests/qualifyingsuffix4.in4 b/keama/tests/qualifyingsuffix4.in4
new file mode 100644
index 00000000..cef53f4d
--- /dev/null
+++ b/keama/tests/qualifyingsuffix4.in4
@@ -0,0 +1,9 @@
+# ddns-domainname (aka qualifying-suffix)
+
+ddns-domainname ".biz";
+ddns-updates true;
+
+# embedded
+class "foo" {
+ ddns-domainname ".bar";
+}
diff --git a/keama/tests/qualifyingsuffix4.out b/keama/tests/qualifyingsuffix4.out
new file mode 100644
index 00000000..f014362d
--- /dev/null
+++ b/keama/tests/qualifyingsuffix4.out
@@ -0,0 +1,17 @@
+{
+ # ddns-domainname (aka qualifying-suffix)
+ "Dhcp4": {
+ "dhcp-ddns": {
+ "qualifying-suffix": ".biz",
+ "enable-updates": true
+ },
+ "client-classes": [
+ # embedded
+ {
+ "name": "foo"
+// /// Only global qualifying-suffix is supported
+// "qualifying-suffix": ".bar"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/qualifyingsuffix6.in6 b/keama/tests/qualifyingsuffix6.in6
new file mode 100644
index 00000000..3957eae2
--- /dev/null
+++ b/keama/tests/qualifyingsuffix6.in6
@@ -0,0 +1,8 @@
+# ddns-domainname (aka qualifying-suffix)
+
+ddns-domainname ".biz";
+
+# embedded
+class "foo" {
+ ddns-domainname ".bar";
+}
diff --git a/keama/tests/qualifyingsuffix6.out b/keama/tests/qualifyingsuffix6.out
new file mode 100644
index 00000000..44ae84a1
--- /dev/null
+++ b/keama/tests/qualifyingsuffix6.out
@@ -0,0 +1,17 @@
+{
+ # ddns-domainname (aka qualifying-suffix)
+ "Dhcp6": {
+ "dhcp-ddns": {
+ "enable-updates": false,
+ "qualifying-suffix": ".biz"
+ },
+ "client-classes": [
+ # embedded
+ {
+ "name": "foo"
+// /// Only global qualifying-suffix is supported
+// "qualifying-suffix": ".bar"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/range4.in4 b/keama/tests/range4.in4
new file mode 100644
index 00000000..f755a2eb
--- /dev/null
+++ b/keama/tests/range4.in4
@@ -0,0 +1,9 @@
+# DHCPv4 range config
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # range declaration
+ option domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ range 10.5.5.5 10.5.5.10;
+}
diff --git a/keama/tests/range4.out b/keama/tests/range4.out
new file mode 100644
index 00000000..94611f7e
--- /dev/null
+++ b/keama/tests/range4.out
@@ -0,0 +1,30 @@
+{
+ # DHCPv4 range config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "subnet4": [
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "option-data": [
+ # range declaration
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "pools": [
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/range6.in6 b/keama/tests/range6.in6
new file mode 100644
index 00000000..45a0635a
--- /dev/null
+++ b/keama/tests/range6.in6
@@ -0,0 +1,11 @@
+# DHCPv6 range config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # range declaration
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ range6 2001::100 2001::200;
+ range6 2001::1000/116;
+ interface "en0";
+}
diff --git a/keama/tests/range6.out b/keama/tests/range6.out
new file mode 100644
index 00000000..1e506ab5
--- /dev/null
+++ b/keama/tests/range6.out
@@ -0,0 +1,37 @@
+{
+ # DHCPv6 range config
+ # subnet declaration
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "option-data": [
+ # range declaration
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "pools": [
+ {
+ "pool": "2001::100 - 2001::200"
+ },
+ {
+ "pool": "2001::1000/116"
+ }
+ ],
+ "interface": "en0"
+ }
+ ],
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ }
+ }
+}
diff --git a/keama/tests/range6in4.err4 b/keama/tests/range6in4.err4
new file mode 100644
index 00000000..af3630c0
--- /dev/null
+++ b/keama/tests/range6in4.err4
@@ -0,0 +1,5 @@
+# DHCPv6 pool declaration in DHCPv4 config
+
+# DHCPv6 pool declaration must be in DHCPv6 config
+range6 2001::/64;
+
diff --git a/keama/tests/range6in4.msg b/keama/tests/range6in4.msg
new file mode 100644
index 00000000..d27a8452
--- /dev/null
+++ b/keama/tests/range6in4.msg
@@ -0,0 +1 @@
+range6in4.err4 line 4: expecting a parameter or declaration
diff --git a/keama/tests/rangeinroot4.err4 b/keama/tests/rangeinroot4.err4
new file mode 100644
index 00000000..7a3d36f9
--- /dev/null
+++ b/keama/tests/rangeinroot4.err4
@@ -0,0 +1,4 @@
+# DHCPv4 range declaration in root config
+
+# DHCPv4 range declaration must be in a subnet declaration
+range 204.152.185.135 204.152.185.185;
diff --git a/keama/tests/rangeinroot4.msg b/keama/tests/rangeinroot4.msg
new file mode 100644
index 00000000..4ed397e4
--- /dev/null
+++ b/keama/tests/rangeinroot4.msg
@@ -0,0 +1 @@
+rangeinroot4.err4 line 4: range declaration not allowed here.
diff --git a/keama/tests/rangeinroot6.err6 b/keama/tests/rangeinroot6.err6
new file mode 100644
index 00000000..e8c5c65e
--- /dev/null
+++ b/keama/tests/rangeinroot6.err6
@@ -0,0 +1,5 @@
+# DHCPv6 range declaration in root config
+
+# DHCPv6 range declaration must be in a subnet declaration
+range6 2001::/64;
+
diff --git a/keama/tests/rangeinroot6.msg b/keama/tests/rangeinroot6.msg
new file mode 100644
index 00000000..969fe658
--- /dev/null
+++ b/keama/tests/rangeinroot6.msg
@@ -0,0 +1 @@
+rangeinroot6.err6 line 4: range6 declaration not allowed here.
diff --git a/keama/tests/reversedx6.in6 b/keama/tests/reversedx6.in6
new file mode 100644
index 00000000..ba762787
--- /dev/null
+++ b/keama/tests/reversedx6.in6
@@ -0,0 +1,9 @@
+# reverse data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# reduce literals
+class "literal" {
+ match if option dhcp6.client-data = reverse(2 & 2, "foobar");
+}
diff --git a/keama/tests/reversedx6.out b/keama/tests/reversedx6.out
new file mode 100644
index 00000000..f13efe95
--- /dev/null
+++ b/keama/tests/reversedx6.out
@@ -0,0 +1,15 @@
+{
+ # reverse data expression
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # reduce literals
+ {
+ "name": "literal",
+ /// from: match if (option dhcp6.client-data) = (reverse(2 & 2, 'foobar'))
+ "test": "option[45].hex == 'arobfo'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/runall.sh b/keama/tests/runall.sh
new file mode 100644
index 00000000..f8cf357e
--- /dev/null
+++ b/keama/tests/runall.sh
@@ -0,0 +1,15 @@
+#!/bin/sh
+
+#set -x
+
+cd "$(dirname "$0")"
+
+echo subdirs:
+/bin/sh samples/runall.sh
+
+echo tests:
+for t in *.err* *.in*
+do
+ echo `basename $t`
+ /bin/sh runone.sh $t
+done
diff --git a/keama/tests/runone.sh b/keama/tests/runone.sh
new file mode 100644
index 00000000..4838c973
--- /dev/null
+++ b/keama/tests/runone.sh
@@ -0,0 +1,119 @@
+#!/bin/sh
+
+#set -x
+
+if [ $# -ne 1 ]; then
+ echo "usage: $0 test-name" >&2
+ exit 1
+fi
+
+file=$1
+
+cd "$(dirname "$0")"
+
+isin=$(expr $file : ".*\.in*")
+iserr=$(expr $file : ".*\.err*")
+if [ \( $isin -eq 0 \) -a \( $iserr -eq 0 \) ]; then
+ full=$file.in*
+ if [ ! -f $full ]; then
+ full=$file.err*
+ fi
+else
+ full=$file
+fi
+
+if [ ! -f $full ]; then
+ echo "can't find $file" >&2
+ exit 1
+fi
+
+errcase=$(expr $full : ".*\.err*")
+
+trail=
+if [ $errcase -eq 0 ]; then
+ trail=$(expr $full : ".*\.in\(.\)")
+else
+ trail=$(expr $full : ".*\.err\(.\)")
+fi
+
+options=""
+dual=0
+hook=0
+
+case $trail in
+ '') dual=1;;
+ 4) options="-4";;
+ 6) options="-6";;
+ F) options="-4 -r fatal";;
+ P) options="-4 -r pass";;
+ d) options="-4 -D";;
+ D) options="-6 -D";;
+ n) options="-4 -N";;
+ N) options="-6 -N";;
+ l) options="-4 -l ${HOOK:-/path/}"; hook=1;;
+ L) options="-6 -l ${HOOK:-/path/}"; hook=1;;
+ *) echo "unrecognized trail '$trail' in '$full'" >&2; exit 1;;
+esac
+
+if [ $errcase -ne 0 ]; then
+ base=$(basename $full .err$trail)
+else
+ if [ $dual -ne 0 ]; then
+ echo "required trail ([45FP]) in '$full'" >&2
+ exit 1
+ fi
+ base=$(basename $full .in$trail)
+fi
+
+out=/tmp/$base.out$$
+expected=""
+if [ $errcase -ne 0 ]; then
+ expected=$base.msg
+else
+ expected=$base.out
+fi
+
+if [ $errcase -ne 0 ]; then
+ if [ $dual -eq 1 ]; then
+ ../keama -4 -i $full >$out 2>&1
+ if [ $? -ne 255 ]; then
+ echo "$full -4 doesn't fail as expected" >&2
+ exit 1
+ fi
+ ../keama -6 -i $full >$out 2>&1
+ if [ $? -ne 255 ]; then
+ echo "$full -6 doesn't fail as expected" >&2
+ exit 1
+ fi
+ else
+ ../keama $options -i $full >$out 2>&1
+ if [ $? -ne 255 ]; then
+ echo "$full doesn't fail as expected" >&2
+ exit 1
+ fi
+ fi
+else
+ ../keama $options -i $full -o $out >&2
+ if [ $? -eq 255 ]; then
+ echo "$full raised an error" >&2
+ exit 1
+ fi
+fi
+
+if [ $hook -eq 1 ]; then
+ sed s,/path/,${HOOK:-/path/}, < ${expected}L > $expected
+fi
+
+if [ $errcase -ne 0 ]; then
+ cat $out | head -1 | diff --brief - $expected
+ if [ $? -ne 0 ]; then
+ echo "$full doesn't provide expected output" >&2
+ exit 1
+ fi
+else
+ diff --brief $out $expected
+ if [ $? -ne 0 ]; then
+ echo "$full doesn't provide expected output" >&2
+ exit 1
+ fi
+fi
diff --git a/keama/tests/samples/example.conf b/keama/tests/samples/example.conf
new file mode 100644
index 00000000..62b088dc
--- /dev/null
+++ b/keama/tests/samples/example.conf
@@ -0,0 +1,111 @@
+# dhcpd.conf
+#
+# Sample configuration file for ISC dhcpd
+#
+
+# option definitions common to all supported networks...
+option domain-name "example.org";
+#option domain-name-servers ns1.example.org, ns2.example.org;
+option domain-name-servers 10.35.0.1, 10.35.0.2;
+
+default-lease-time 600;
+max-lease-time 7200;
+
+# Use this to enble / disable dynamic dns updates globally.
+#ddns-update-style none;
+
+# If this DHCP server is the official DHCP server for the local
+# network, the authoritative directive should be uncommented.
+#authoritative;
+
+# Use this to send dhcp log messages to a different log file (you also
+# have to hack syslog.conf to complete the redirection).
+log-facility local7;
+
+# No service will be given on this subnet, but declaring it helps the
+# DHCP server to understand the network topology.
+
+subnet 10.152.187.0 netmask 255.255.255.0 {
+}
+
+# This is a very basic subnet declaration.
+
+subnet 10.254.239.0 netmask 255.255.255.224 {
+ range 10.254.239.10 10.254.239.20;
+# option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
+ option routers 10.254.239.1, 10.254.239.2;
+}
+
+# This declaration allows BOOTP clients to get dynamic addresses,
+# which we don't really recommend.
+
+subnet 10.254.239.32 netmask 255.255.255.224 {
+ range dynamic-bootp 10.254.239.40 10.254.239.60;
+ option broadcast-address 10.254.239.31;
+# option routers rtr-239-32-1.example.org;
+ option routers 10.254.239.33;
+}
+
+# A slightly different configuration for an internal subnet.
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ range 10.5.5.26 10.5.5.30;
+# option domain-name-servers ns1.internal.example.org;
+ option domain-name-servers 10.35.1.1;
+ option domain-name "internal.example.org";
+ option routers 10.5.5.1;
+ option broadcast-address 10.5.5.31;
+ default-lease-time 600;
+ max-lease-time 7200;
+}
+
+# Hosts which require special configuration options can be listed in
+# host statements. If no address is specified, the address will be
+# allocated dynamically (if possible), but the host-specific information
+# will still come from the host declaration.
+
+host passacaglia {
+ hardware ethernet 0:0:c0:5d:bd:95;
+ filename "vmunix.passacaglia";
+ server-name "toccata.example.com";
+}
+
+# Fixed IP addresses can also be specified for hosts. These addresses
+# should not also be listed as being available for dynamic assignment.
+# Hosts for which fixed IP addresses have been specified can boot using
+# BOOTP or DHCP. Hosts for which no fixed address is specified can only
+# be booted with DHCP, unless there is an address range on the subnet
+# to which a BOOTP client is connected which has the dynamic-bootp flag
+# set.
+host fantasia {
+ hardware ethernet 08:00:07:26:c0:a5;
+# fixed-address fantasia.example.com;
+ fixed-address 10.5.5.20;
+}
+
+# You can declare a class of clients and then do address allocation
+# based on that. The example below shows a case where all clients
+# in a certain class get addresses on the 10.17.224/24 subnet, and all
+# other clients get addresses on the 10.0.29/24 subnet.
+
+class "foo" {
+ match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
+}
+
+shared-network 224-29 {
+ subnet 10.17.224.0 netmask 255.255.255.0 {
+# option routers rtr-224.example.org;
+ option routers 10.17.224.1;
+ }
+ subnet 10.0.29.0 netmask 255.255.255.0 {
+# option routers rtr-29.example.org;
+ option routers 10.0.29.1;
+ }
+ pool {
+ allow members of "foo";
+ range 10.17.224.10 10.17.224.250;
+ }
+ pool {
+ deny members of "foo";
+ range 10.0.29.10 10.0.29.230;
+ }
+}
diff --git a/keama/tests/samples/example.conf.orig b/keama/tests/samples/example.conf.orig
new file mode 100644
index 00000000..8b99f496
--- /dev/null
+++ b/keama/tests/samples/example.conf.orig
@@ -0,0 +1,104 @@
+# dhcpd.conf
+#
+# Sample configuration file for ISC dhcpd
+#
+
+# option definitions common to all supported networks...
+option domain-name "example.org";
+option domain-name-servers ns1.example.org, ns2.example.org;
+
+default-lease-time 600;
+max-lease-time 7200;
+
+# Use this to enble / disable dynamic dns updates globally.
+#ddns-update-style none;
+
+# If this DHCP server is the official DHCP server for the local
+# network, the authoritative directive should be uncommented.
+#authoritative;
+
+# Use this to send dhcp log messages to a different log file (you also
+# have to hack syslog.conf to complete the redirection).
+log-facility local7;
+
+# No service will be given on this subnet, but declaring it helps the
+# DHCP server to understand the network topology.
+
+subnet 10.152.187.0 netmask 255.255.255.0 {
+}
+
+# This is a very basic subnet declaration.
+
+subnet 10.254.239.0 netmask 255.255.255.224 {
+ range 10.254.239.10 10.254.239.20;
+ option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
+}
+
+# This declaration allows BOOTP clients to get dynamic addresses,
+# which we don't really recommend.
+
+subnet 10.254.239.32 netmask 255.255.255.224 {
+ range dynamic-bootp 10.254.239.40 10.254.239.60;
+ option broadcast-address 10.254.239.31;
+ option routers rtr-239-32-1.example.org;
+}
+
+# A slightly different configuration for an internal subnet.
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ range 10.5.5.26 10.5.5.30;
+ option domain-name-servers ns1.internal.example.org;
+ option domain-name "internal.example.org";
+ option routers 10.5.5.1;
+ option broadcast-address 10.5.5.31;
+ default-lease-time 600;
+ max-lease-time 7200;
+}
+
+# Hosts which require special configuration options can be listed in
+# host statements. If no address is specified, the address will be
+# allocated dynamically (if possible), but the host-specific information
+# will still come from the host declaration.
+
+host passacaglia {
+ hardware ethernet 0:0:c0:5d:bd:95;
+ filename "vmunix.passacaglia";
+ server-name "toccata.example.com";
+}
+
+# Fixed IP addresses can also be specified for hosts. These addresses
+# should not also be listed as being available for dynamic assignment.
+# Hosts for which fixed IP addresses have been specified can boot using
+# BOOTP or DHCP. Hosts for which no fixed address is specified can only
+# be booted with DHCP, unless there is an address range on the subnet
+# to which a BOOTP client is connected which has the dynamic-bootp flag
+# set.
+host fantasia {
+ hardware ethernet 08:00:07:26:c0:a5;
+ fixed-address fantasia.example.com;
+}
+
+# You can declare a class of clients and then do address allocation
+# based on that. The example below shows a case where all clients
+# in a certain class get addresses on the 10.17.224/24 subnet, and all
+# other clients get addresses on the 10.0.29/24 subnet.
+
+class "foo" {
+ match if substring (option vendor-class-identifier, 0, 4) = "SUNW";
+}
+
+shared-network 224-29 {
+ subnet 10.17.224.0 netmask 255.255.255.0 {
+ option routers rtr-224.example.org;
+ }
+ subnet 10.0.29.0 netmask 255.255.255.0 {
+ option routers rtr-29.example.org;
+ }
+ pool {
+ allow members of "foo";
+ range 10.17.224.10 10.17.224.250;
+ }
+ pool {
+ deny members of "foo";
+ range 10.0.29.10 10.0.29.230;
+ }
+}
diff --git a/keama/tests/samples/example.json b/keama/tests/samples/example.json
new file mode 100644
index 00000000..7123a158
--- /dev/null
+++ b/keama/tests/samples/example.json
@@ -0,0 +1,223 @@
+{
+ # dhcpd.conf
+ #
+ # Sample configuration file for ISC dhcpd
+ #
+ # option definitions common to all supported networks...
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-name",
+ "code": 15,
+ "data": "example.org"
+ },
+ #option domain-name-servers ns1.example.org, ns2.example.org;
+ {
+ "space": "dhcp4",
+ "name": "domain-name-servers",
+ "code": 6,
+ "data": "10.35.0.1, 10.35.0.2"
+ }
+ ],
+ "valid-lifetime": 600,
+ "max-valid-lifetime": 7200,
+// "config": [
+// /// log-facility is not supported
+// /// Please use the KEA_LOGGER_DESTINATION environment variable instead
+// {
+// "name": "log-facility",
+// "code": 44,
+// "value": "local7"
+// }
+// ],
+ "subnet4": [
+ # No service will be given on this subnet, but declaring it helps the
+ # DHCP server to understand the network topology.
+ {
+ "id": 1,
+ "subnet": "10.152.187.0/24"
+ },
+ # This is a very basic subnet declaration.
+ {
+ "id": 2,
+ "subnet": "10.254.239.0/27",
+ "pools": [
+ {
+ "pool": "10.254.239.10 - 10.254.239.20"
+ }
+ ],
+ "option-data": [
+ # option routers rtr-239-0-1.example.org, rtr-239-0-2.example.org;
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "10.254.239.1, 10.254.239.2"
+ }
+ ]
+ },
+ # This declaration allows BOOTP clients to get dynamic addresses,
+ # which we don't really recommend.
+ {
+ "id": 3,
+ "subnet": "10.254.239.32/27",
+ "pools": [
+ {
+ "pool": "10.254.239.40 - 10.254.239.60"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "broadcast-address",
+ "code": 28,
+ "data": "10.254.239.31"
+ },
+ # option routers rtr-239-32-1.example.org;
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "10.254.239.33"
+ }
+ ]
+ },
+ # A slightly different configuration for an internal subnet.
+ {
+ "id": 4,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ {
+ "pool": "10.5.5.26 - 10.5.5.30"
+ }
+ ],
+ "option-data": [
+ # option domain-name-servers ns1.internal.example.org;
+ {
+ "space": "dhcp4",
+ "name": "domain-name-servers",
+ "code": 6,
+ "data": "10.35.1.1"
+ },
+ {
+ "space": "dhcp4",
+ "name": "domain-name",
+ "code": 15,
+ "data": "internal.example.org"
+ },
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "10.5.5.1"
+ },
+ {
+ "space": "dhcp4",
+ "name": "broadcast-address",
+ "code": 28,
+ "data": "10.5.5.31"
+ }
+ ],
+ "valid-lifetime": 600,
+ "max-valid-lifetime": 7200,
+ /// Host reservations without fixed addresses were put in the last declared subnet
+ /// Reference Kea #231
+ "reservations": [
+ # Hosts which require special configuration options can be listed in
+ # host statements. If no address is specified, the address will be
+ # allocated dynamically (if possible), but the host-specific information
+ # will still come from the host declaration.
+ {
+ "hostname": "passacaglia",
+ "hw-address": "00:00:c0:5d:bd:95",
+ "boot-file-name": "vmunix.passacaglia",
+ "server-hostname": "toccata.example.com"
+ },
+ # Fixed IP addresses can also be specified for hosts. These addresses
+ # should not also be listed as being available for dynamic assignment.
+ # Hosts for which fixed IP addresses have been specified can boot using
+ # BOOTP or DHCP. Hosts for which no fixed address is specified can only
+ # be booted with DHCP, unless there is an address range on the subnet
+ # to which a BOOTP client is connected which has the dynamic-bootp flag
+ # set.
+ {
+ "hostname": "fantasia",
+ "hw-address": "08:00:07:26:c0:a5",
+ "ip-address": "10.5.5.20"
+ }
+ ]
+ }
+ ],
+ "host-reservation-identifiers": [
+ "hw-address"
+ ],
+ "client-classes": [
+ # You can declare a class of clients and then do address allocation
+ # based on that. The example below shows a case where all clients
+ # in a certain class get addresses on the 10.17.224/24 subnet, and all
+ # other clients get addresses on the 10.0.29/24 subnet.
+ {
+ "name": "foo",
+ /// from: match if (substring(option dhcp.vendor-class-identifier, 0, 4)) = 'SUNW'
+ "test": "substring(option[60].hex,0,4) == 'SUNW'"
+ },
+ {
+ "name": "gen#_AND_#!foo#",
+ "test": "not member('foo')"
+ }
+ ],
+ /// Kea shared-networks are different, cf Kea #236
+ "shared-networks": [
+ {
+ "name": "224-29",
+ "subnet4": [
+ {
+ "id": 5,
+ "subnet": "10.17.224.0/24",
+ "option-data": [
+ # option routers rtr-224.example.org;
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "10.17.224.1"
+ }
+ ],
+ "pools": [
+ {
+ "pool": "10.17.224.10 - 10.17.224.250",
+ /// From:
+ /// allow foo
+ "client-class": "foo"
+ }
+ ]
+ },
+ {
+ "id": 6,
+ "subnet": "10.0.29.0/24",
+ "option-data": [
+ # option routers rtr-29.example.org;
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "10.0.29.1"
+ }
+ ],
+ "pools": [
+ {
+ "pool": "10.0.29.10 - 10.0.29.230",
+ /// From:
+ /// deny foo
+ "client-class": "gen#_AND_#!foo#"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/samples/runall.sh b/keama/tests/samples/runall.sh
new file mode 100644
index 00000000..bc41c7f8
--- /dev/null
+++ b/keama/tests/samples/runall.sh
@@ -0,0 +1,11 @@
+#!/bin/sh
+
+#set -x
+
+cd "$(dirname "$0")"
+
+for t in example simple test-a6 vmnet8
+do
+ echo $t
+ /bin/sh runone.sh $t
+done
diff --git a/keama/tests/samples/runone.sh b/keama/tests/samples/runone.sh
new file mode 100644
index 00000000..6526d798
--- /dev/null
+++ b/keama/tests/samples/runone.sh
@@ -0,0 +1,39 @@
+#!/bin/sh
+
+#set -x
+
+if [ $# -ne 1 ]; then
+ echo "usage: $0 config-name" >&2
+ exit 1
+fi
+
+file=$1
+
+cd "$(dirname "$0")"
+
+trail=$(expr $file : ".*6$")
+options=""
+if [ $trail -eq 0 ]; then
+ options="-4"
+else
+ options="-6"
+fi
+
+out=/tmp/$file.out$$
+
+../../keama $options -N -i $file.conf -o $out >&2
+status=$?
+if [ $status -eq 255 ]; then
+ echo "$file config raised an error" >&2
+ exit 1
+fi
+
+expected=$file.json
+
+diff --brief $out $expected
+if [ $? -ne 0 ]; then
+ echo "$file config doesn't provide expected output" >&2
+ exit 1
+fi
+
+exit $status
diff --git a/keama/tests/samples/simple.conf b/keama/tests/samples/simple.conf
new file mode 100644
index 00000000..76c1cfa5
--- /dev/null
+++ b/keama/tests/samples/simple.conf
@@ -0,0 +1,33 @@
+# -------------------------
+# dhcpd.conf
+#
+# Sample configuration file for ISC dhcpd
+#
+
+# option definitions common to all supported networks...
+option domain-name "example.org";
+# option domain-name-servers ns1.example.org, ns2.example.org;
+
+default-lease-time 1800;
+max-lease-time 7200;
+
+# We're going to be authoritative for the network we've
+# just created.
+
+authoritative;
+
+# No service will be given on this subnet, but we're telling
+# the DHCP server about it so it understands it's there and
+# not to hand out leases for it.
+
+subnet 10.14.8.195 netmask 255.255.255.0 {
+}
+
+# But we do want to hand out leases for the 192.168.1.0/24
+# network for purposes of this test..
+
+subnet 192.168.1.0 netmask 255.255.255.0 {
+ range 192.168.1.100 192.168.1.150;
+ option routers 192.168.1.1;
+}
+# -------------------------
diff --git a/keama/tests/samples/simple.json b/keama/tests/samples/simple.json
new file mode 100644
index 00000000..7cd02423
--- /dev/null
+++ b/keama/tests/samples/simple.json
@@ -0,0 +1,53 @@
+{
+ # -------------------------
+ # dhcpd.conf
+ #
+ # Sample configuration file for ISC dhcpd
+ #
+ # option definitions common to all supported networks...
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-name",
+ "code": 15,
+ "data": "example.org"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "max-valid-lifetime": 7200,
+ # We're going to be authoritative for the network we've
+ # just created.
+ "authoritative": true,
+ "subnet4": [
+ # No service will be given on this subnet, but we're telling
+ # the DHCP server about it so it understands it's there and
+ # not to hand out leases for it.
+ {
+ "id": 1,
+ "subnet": "10.14.8.195/24"
+ },
+ # But we do want to hand out leases for the 192.168.1.0/24
+ # network for purposes of this test..
+ {
+ "id": 2,
+ "subnet": "192.168.1.0/24",
+ "pools": [
+ {
+ "pool": "192.168.1.100 - 192.168.1.150"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "192.168.1.1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/samples/test-a6.conf b/keama/tests/samples/test-a6.conf
new file mode 100644
index 00000000..9514c4aa
--- /dev/null
+++ b/keama/tests/samples/test-a6.conf
@@ -0,0 +1,75 @@
+#
+# Define the DHCPv6 option space.
+#
+# Option numbers are assigned by IANA:
+# http://www.iana.org/assignments/dhcpv6-parameters
+#
+option dhcp6.time-servers code 1040 = array of ip6-address;
+option dhcp6.time-offset code 1041 = signed integer 32;
+
+#
+# Define the DOCSIS option space.
+# TODO: DOCSIS oro definition
+#
+# this space is already known by Kea
+option space docsis code width 2 length width 2;
+option vsio.docsis code 4491 = encapsulate docsis;
+option docsis.tftp-servers code 32 = array of ip6-address;
+% option docsis.tftp-servers local;
+option docsis.cablelabs-configuration-file code 33 = text;
+% option docsis.cablelabs-configuration-file alias config-file;
+% option docsis.cablelabs-configuration-file local;
+option docsis.cablelabs-syslog-servers code 34 = array of ip6-address;
+% option docsis.cablelabs-syslog-servers alias syslog-servers;
+% option docsis.cablelabs-syslog-servers local;
+#option docsis.device-id code 36 = string;
+% option docsis.device-id code 36 = "X";
+% option docsis.device-id local;
+
+#
+# Declare some options.
+#
+option dhcp6.time-servers 3ffe:bbbb:aaaa:aaaa::1, 3ffe:bbbb:aaaa:aaaa::2;
+option docsis.tftp-servers 3ffe:cccc:aaaa:aaaa::1, 3ffe:cccc:aaaa:aaaa::2;
+
+#
+# DNS server IP address to update dynamically
+#
+ddns-update-style interim;
+ddns-domainname "foo.com";
+
+#
+# Per-host settings.
+#
+host cablemodem-1 {
+ host-identifier option
+ dhcp6.client-id 00:01:00:01:0c:00:a1:41:00:06:5b:50:99:f6;
+ fixed-address6 3ffe:aaaa:aaaa:aaaa::ffff;
+ ddns-domainname "bar.com";
+ option dhcp6.time-servers 3ffe:aaaa:aaaa:aaaa::1,
+ 3ffe:aaaa:aaaa:aaaa::2;
+ option docsis.tftp-servers 3ffe:aaaa:aaaa:aaaa::1,
+ 3ffe:aaaa:aaaa:aaaa::2;
+ option dhcp6.time-offset -14400; # -4 hours
+ option docsis.cablelabs-configuration-file "bootfile.cfg";
+ option docsis.cablelabs-syslog-servers 3ffe:aaaa:aaaa:aaaa::1,
+ 3ffe:aaaa:aaaa:aaaa::2;
+}
+
+#host cablemodem-2 {
+# host-identifier option docsis.device-id 00:06:5B:50:99:F6;
+# option dhcp6.time-servers 3ffe:dddd:aaaa:aaaa::1,
+# 3ffe:dddd:aaaa:aaaa::2;
+# option docsis.tftp-servers 3ffe:dddd:aaaa:aaaa::1,
+# 3ffe:dddd:aaaa:aaaa::2;
+# option dhcp6.time-offset -14400; # -4 hours
+# option docsis.cablelabs-configuration-file "bootfile.cfg";
+# option docsis.cablelabs-syslog-servers 3ffe:aaaa:aaaa:aaaa::1,
+# 3ffe:aaaa:aaaa:aaaa::2;
+#}
+
+# XXX: for testing
+subnet6 3ffe:aaaa:aaaa:aaaa::/64 {
+}
+
+
diff --git a/keama/tests/samples/test-a6.conf.orig b/keama/tests/samples/test-a6.conf.orig
new file mode 100644
index 00000000..9fe42364
--- /dev/null
+++ b/keama/tests/samples/test-a6.conf.orig
@@ -0,0 +1,67 @@
+#
+# Define the DHCPv6 option space.
+#
+# Option numbers are assigned by IANA:
+# http://www.iana.org/assignments/dhcpv6-parameters
+#
+option dhcp6.time-servers code 40 = array of ip6-address;
+option dhcp6.time-offset code 41 = signed integer 32;
+
+#
+# Define the DOCSIS option space.
+# TODO: DOCSIS oro definition
+#
+option space docsis code width 2 length width 2;
+option vsio.docsis code 4491 = encapsulate docsis;
+option docsis.tftp-servers code 32 = array of ip6-address;
+option docsis.cablelabs-configuration-file code 33 = text;
+option docsis.cablelabs-syslog-servers code 34 = array of ip6-address;
+option docsis.device-id code 36 = string;
+
+#
+# Declare some options.
+#
+option dhcp6.time-servers 3ffe:bbbb:aaaa:aaaa::1, 3ffe:bbbb:aaaa:aaaa::2;
+option docsis.tftp-servers 3ffe:cccc:aaaa:aaaa::1, 3ffe:cccc:aaaa:aaaa::2;
+
+#
+# DNS server IP address to update dynamically
+#
+ddns-update-style interim;
+ddns-domainname "foo.com";
+
+#
+# Per-host settings.
+#
+host cablemodem-1 {
+ host-identifier option
+ dhcp6.client-id 00:01:00:01:0c:00:a1:41:00:06:5b:50:99:f6;
+ fixed-address6 3ffe:aaaa:aaaa:aaaa::ffff;
+ ddns-domainname "bar.com";
+ option dhcp6.time-servers 3ffe:aaaa:aaaa:aaaa::1,
+ 3ffe:aaaa:aaaa:aaaa::2;
+ option docsis.tftp-servers 3ffe:aaaa:aaaa:aaaa::1,
+ 3ffe:aaaa:aaaa:aaaa::2;
+ option dhcp6.time-offset -14400; # -4 hours
+ option docsis.cablelabs-configuration-file "bootfile.cfg";
+ option docsis.cablelabs-syslog-servers 3ffe:aaaa:aaaa:aaaa::1,
+ 3ffe:aaaa:aaaa:aaaa::2;
+}
+
+#host cablemodem-2 {
+# host-identifier option docsis.device-id 00:06:5B:50:99:F6;
+# option dhcp6.time-servers 3ffe:dddd:aaaa:aaaa::1,
+# 3ffe:dddd:aaaa:aaaa::2;
+# option docsis.tftp-servers 3ffe:dddd:aaaa:aaaa::1,
+# 3ffe:dddd:aaaa:aaaa::2;
+# option dhcp6.time-offset -14400; # -4 hours
+# option docsis.cablelabs-configuration-file "bootfile.cfg";
+# option docsis.cablelabs-syslog-servers 3ffe:aaaa:aaaa:aaaa::1,
+# 3ffe:aaaa:aaaa:aaaa::2;
+#}
+
+# XXX: for testing
+subnet6 fe80::20c:29ff:fe42:820/128 {
+}
+
+
diff --git a/keama/tests/samples/test-a6.json b/keama/tests/samples/test-a6.json
new file mode 100644
index 00000000..8b768686
--- /dev/null
+++ b/keama/tests/samples/test-a6.json
@@ -0,0 +1,144 @@
+{
+ #
+ # Define the DHCPv6 option space.
+ #
+ # Option numbers are assigned by IANA:
+ # http://www.iana.org/assignments/dhcpv6-parameters
+ #
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "time-servers",
+ "code": 1040,
+ "array": true,
+ "type": "ipv6-address"
+ },
+ {
+ "space": "dhcp6",
+ "name": "time-offset",
+ "code": 1041,
+ "type": "int32"
+ }
+ ],
+ "option-data": [
+ #option docsis.device-id code 36 = string;
+ #
+ # Declare some options.
+ #
+ {
+ "space": "dhcp6",
+ "name": "time-servers",
+ "code": 1040,
+ "data": "3ffe:bbbb:aaaa:aaaa::1, 3ffe:bbbb:aaaa:aaaa::2"
+ },
+ {
+ "space": "dhcp6",
+ "name": "vendor-opts",
+ "code": 17,
+ "data": "4491"
+ },
+ {
+ "space": "vendor-4491",
+ "name": "tftp-servers",
+ "code": 32,
+ "data": "3ffe:cccc:aaaa:aaaa::1, 3ffe:cccc:aaaa:aaaa::2"
+ }
+ ],
+// /// Unsupported ddns-update-style interim
+// "ddns-update-style": "interim",
+ "dhcp-ddns": {
+ "enable-updates": true,
+ "qualifying-suffix": "foo.com"
+ },
+ "host-reservation-identifiers": [
+ "flex-id"
+ ],
+ /// The flexible host identifier is a premium feature
+ "hooks-libraries": [
+ {
+ /// Please update the path here
+ "library": "/path/libdhcp_flex_id.so",
+ "parameters": {
+ "identifier-expression": "option[1].hex"
+ }
+ }
+ ],
+ "subnet6": [
+ #host cablemodem-2 {
+ # host-identifier option docsis.device-id 00:06:5B:50:99:F6;
+ # option dhcp6.time-servers 3ffe:dddd:aaaa:aaaa::1,
+ # 3ffe:dddd:aaaa:aaaa::2;
+ # option docsis.tftp-servers 3ffe:dddd:aaaa:aaaa::1,
+ # 3ffe:dddd:aaaa:aaaa::2;
+ # option dhcp6.time-offset -14400; # -4 hours
+ # option docsis.cablelabs-configuration-file "bootfile.cfg";
+ # option docsis.cablelabs-syslog-servers 3ffe:aaaa:aaaa:aaaa::1,
+ # 3ffe:aaaa:aaaa:aaaa::2;
+ #}
+ # XXX: for testing
+ {
+ "id": 1,
+ "subnet": "3ffe:aaaa:aaaa:aaaa::/64",
+ "reservations": [
+ #
+ # Per-host settings.
+ #
+ {
+ "hostname": "cablemodem-1",
+ "flex-id": "000100010c00a14100065b5099f6",
+ "ip-addresses": [
+ "3ffe:aaaa:aaaa:aaaa::ffff"
+ ],
+// /// Only global qualifying-suffix is supported
+// "qualifying-suffix": "bar.com",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "time-servers",
+ "code": 1040,
+// "original-data": "3ffe:aaaa:aaaa:aaaa::1, \n\t\t\t\t 3ffe:aaaa:aaaa:aaaa::2",
+ "data": "3ffe:aaaa:aaaa:aaaa::1, 3ffe:aaaa:aaaa:aaaa::2"
+ },
+ {
+ "space": "dhcp6",
+ "name": "vendor-opts",
+ "code": 17,
+ "data": "4491"
+ },
+ {
+ "space": "vendor-4491",
+ "name": "tftp-servers",
+ "code": 32,
+// "original-data": "3ffe:aaaa:aaaa:aaaa::1,\n\t\t\t\t 3ffe:aaaa:aaaa:aaaa::2",
+ "data": "3ffe:aaaa:aaaa:aaaa::1, 3ffe:aaaa:aaaa:aaaa::2"
+ },
+ {
+ "space": "dhcp6",
+ "name": "time-offset",
+ "code": 1041,
+ "data": "-14400"
+ },
+ # -4 hours
+ {
+ "space": "vendor-4491",
+ "name": "config-file",
+ "code": 33,
+ "data": "bootfile.cfg"
+ },
+ {
+ "space": "vendor-4491",
+ "name": "syslog-servers",
+ "code": 34,
+// "original-data": "3ffe:aaaa:aaaa:aaaa::1,\n\t\t\t\t\t 3ffe:aaaa:aaaa:aaaa::2",
+ "data": "3ffe:aaaa:aaaa:aaaa::1, 3ffe:aaaa:aaaa:aaaa::2"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/samples/vmnet8.conf b/keama/tests/samples/vmnet8.conf
new file mode 100644
index 00000000..9484938e
--- /dev/null
+++ b/keama/tests/samples/vmnet8.conf
@@ -0,0 +1,43 @@
+# Configuration file for ISC 2.0 vmnet-dhcpd operating on vmnet8.
+#
+# This file was automatically generated by the VMware configuration program.
+# See Instructions below if you want to modify it.
+#
+# We set domain-name-servers to make some DHCP clients happy
+# (dhclient as configured in SuSE, TurboLinux, etc.).
+# We also supply a domain name to make pump (Red Hat 6.x) happy.
+#
+
+
+###### VMNET DHCP Configuration. Start of "DO NOT MODIFY SECTION" #####
+# Modification Instructions: This section of the configuration file contains
+# information generated by the configuration program. Do not modify this
+# section.
+# You are free to modify everything else. Also, this section must start
+# on a new line
+# This file will get backed up with a different name in the same directory
+# if this section is edited and you try to configure DHCP again.
+
+# Written at: 04/12/2017 14:00:17
+allow unknown-clients;
+default-lease-time 1800; # default is 30 minutes
+max-lease-time 7200; # default is 2 hours
+
+subnet 172.16.254.0 netmask 255.255.255.0 {
+ range 172.16.254.128 172.16.254.254;
+ option broadcast-address 172.16.254.255;
+ option domain-name-servers 172.16.254.2;
+ option domain-name localdomain;
+ default-lease-time 1800; # default is 30 minutes
+ max-lease-time 7200; # default is 2 hours
+ option netbios-name-servers 172.16.254.2;
+ option routers 172.16.254.2;
+}
+host vmnet8 {
+ hardware ethernet 00:50:56:C0:00:08;
+ fixed-address 172.16.254.1;
+ option domain-name-servers 0.0.0.0;
+# option domain-name "";
+ option routers 0.0.0.0;
+}
+####### VMNET DHCP Configuration. End of "DO NOT MODIFY SECTION" #######
diff --git a/keama/tests/samples/vmnet8.conf.orig b/keama/tests/samples/vmnet8.conf.orig
new file mode 100644
index 00000000..313deca7
--- /dev/null
+++ b/keama/tests/samples/vmnet8.conf.orig
@@ -0,0 +1,43 @@
+# Configuration file for ISC 2.0 vmnet-dhcpd operating on vmnet8.
+#
+# This file was automatically generated by the VMware configuration program.
+# See Instructions below if you want to modify it.
+#
+# We set domain-name-servers to make some DHCP clients happy
+# (dhclient as configured in SuSE, TurboLinux, etc.).
+# We also supply a domain name to make pump (Red Hat 6.x) happy.
+#
+
+
+###### VMNET DHCP Configuration. Start of "DO NOT MODIFY SECTION" #####
+# Modification Instructions: This section of the configuration file contains
+# information generated by the configuration program. Do not modify this
+# section.
+# You are free to modify everything else. Also, this section must start
+# on a new line
+# This file will get backed up with a different name in the same directory
+# if this section is edited and you try to configure DHCP again.
+
+# Written at: 04/12/2017 14:00:17
+allow unknown-clients;
+default-lease-time 1800; # default is 30 minutes
+max-lease-time 7200; # default is 2 hours
+
+subnet 172.16.254.0 netmask 255.255.255.0 {
+ range 172.16.254.128 172.16.254.254;
+ option broadcast-address 172.16.254.255;
+ option domain-name-servers 172.16.254.2;
+ option domain-name localdomain;
+ default-lease-time 1800; # default is 30 minutes
+ max-lease-time 7200; # default is 2 hours
+ option netbios-name-servers 172.16.254.2;
+ option routers 172.16.254.2;
+}
+host vmnet8 {
+ hardware ethernet 00:50:56:C0:00:08;
+ fixed-address 172.16.254.1;
+ option domain-name-servers 0.0.0.0;
+ option domain-name "";
+ option routers 0.0.0.0;
+}
+####### VMNET DHCP Configuration. End of "DO NOT MODIFY SECTION" #######
diff --git a/keama/tests/samples/vmnet8.json b/keama/tests/samples/vmnet8.json
new file mode 100644
index 00000000..9b207ff8
--- /dev/null
+++ b/keama/tests/samples/vmnet8.json
@@ -0,0 +1,105 @@
+{
+ # Configuration file for ISC 2.0 vmnet-dhcpd operating on vmnet8.
+ #
+ # This file was automatically generated by the VMware configuration program.
+ # See Instructions below if you want to modify it.
+ #
+ # We set domain-name-servers to make some DHCP clients happy
+ # (dhclient as configured in SuSE, TurboLinux, etc.).
+ # We also supply a domain name to make pump (Red Hat 6.x) happy.
+ #
+ ###### VMNET DHCP Configuration. Start of "DO NOT MODIFY SECTION" #####
+ # Modification Instructions: This section of the configuration file contains
+ # information generated by the configuration program. Do not modify this
+ # section.
+ # You are free to modify everything else. Also, this section must start
+ # on a new line
+ # This file will get backed up with a different name in the same directory
+ # if this section is edited and you try to configure DHCP again.
+ # Written at: 04/12/2017 14:00:17
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+// "statement": {
+// "config": {
+// "value": "allow",
+// "name": "boot-unknown-clients",
+// "code": 6
+// }
+// },
+ "valid-lifetime": 1800,
+ "max-valid-lifetime": 7200,
+ "subnet4": [
+ # default is 2 hours
+ {
+ "id": 1,
+ "subnet": "172.16.254.0/24",
+ "pools": [
+ {
+ "pool": "172.16.254.128 - 172.16.254.254"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "broadcast-address",
+ "code": 28,
+ "data": "172.16.254.255"
+ },
+ {
+ "space": "dhcp4",
+ "name": "domain-name-servers",
+ "code": 6,
+ "data": "172.16.254.2"
+ },
+ {
+ "space": "dhcp4",
+ "name": "domain-name",
+ "code": 15,
+ "data": "localdomain"
+ },
+ # default is 2 hours
+ {
+ "space": "dhcp4",
+ "name": "netbios-name-servers",
+ "code": 44,
+ "data": "172.16.254.2"
+ },
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "172.16.254.2"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "max-valid-lifetime": 7200,
+ "reservations": [
+ {
+ "hostname": "vmnet8",
+ "hw-address": "00:50:56:c0:00:08",
+ "ip-address": "172.16.254.1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-name-servers",
+ "code": 6,
+ "data": "0.0.0.0"
+ },
+ # option domain-name "";
+ {
+ "space": "dhcp4",
+ "name": "routers",
+ "code": 3,
+ "data": "0.0.0.0"
+ }
+ ]
+ }
+ ]
+ }
+ ],
+ "host-reservation-identifiers": [
+ "hw-address"
+ ]
+ }
+}
diff --git a/keama/tests/share0.err b/keama/tests/share0.err
new file mode 100644
index 00000000..6b2184e4
--- /dev/null
+++ b/keama/tests/share0.err
@@ -0,0 +1,6 @@
+# bad (empty name)shared-network declaration config
+
+# shared-network declaration
+shared-network "" {
+
+}
diff --git a/keama/tests/share0.msg b/keama/tests/share0.msg
new file mode 100644
index 00000000..4296f4e8
--- /dev/null
+++ b/keama/tests/share0.msg
@@ -0,0 +1 @@
+share0.err line 4: zero-length shared network name
diff --git a/keama/tests/share2if.err b/keama/tests/share2if.err
new file mode 100644
index 00000000..2c40326d
--- /dev/null
+++ b/keama/tests/share2if.err
@@ -0,0 +1,7 @@
+# bad (2 interfaces)shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ interface "foo";
+ interface "bar";
+}
diff --git a/keama/tests/share2if.msg b/keama/tests/share2if.msg
new file mode 100644
index 00000000..bc4b9c10
--- /dev/null
+++ b/keama/tests/share2if.msg
@@ -0,0 +1 @@
+share2if.err line 6: A shared network can't be connected to two interfaces.
diff --git a/keama/tests/shareempty.err b/keama/tests/shareempty.err
new file mode 100644
index 00000000..2e9e3a12
--- /dev/null
+++ b/keama/tests/shareempty.err
@@ -0,0 +1,6 @@
+# bad (no subnet) shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ interface "foo";
+}
diff --git a/keama/tests/shareempty.msg b/keama/tests/shareempty.msg
new file mode 100644
index 00000000..fb74cc62
--- /dev/null
+++ b/keama/tests/shareempty.msg
@@ -0,0 +1 @@
+shareempty.err line 6: empty shared-network decl
diff --git a/keama/tests/shareinclass.err b/keama/tests/shareinclass.err
new file mode 100644
index 00000000..d68e724e
--- /dev/null
+++ b/keama/tests/shareinclass.err
@@ -0,0 +1,11 @@
+# shared-network declaration inside class declaration config
+
+# class declaration
+class "foobar" {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ # can't put a shared-network declaration here
+ shared-network "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/shareinclass.msg b/keama/tests/shareinclass.msg
new file mode 100644
index 00000000..656898c2
--- /dev/null
+++ b/keama/tests/shareinclass.msg
@@ -0,0 +1 @@
+shareinclass.err line 5: hardware address parameter not allowed here.
diff --git a/keama/tests/shareinhost.err b/keama/tests/shareinhost.err
new file mode 100644
index 00000000..93b049c7
--- /dev/null
+++ b/keama/tests/shareinhost.err
@@ -0,0 +1,11 @@
+# shared-network declaration inside host declaration config
+
+# host declaration
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ # can't put a shared-network declaration here
+ shared-network "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/shareinhost.msg b/keama/tests/shareinhost.msg
new file mode 100644
index 00000000..22da166d
--- /dev/null
+++ b/keama/tests/shareinhost.msg
@@ -0,0 +1 @@
+shareinhost.err line 7: shared-network parameters not allowed here.
diff --git a/keama/tests/shareinshare.err b/keama/tests/shareinshare.err
new file mode 100644
index 00000000..68750613
--- /dev/null
+++ b/keama/tests/shareinshare.err
@@ -0,0 +1,10 @@
+# shared-network declaration inside shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ # can't put another shared-network declaration here
+ shared-network "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/shareinshare.msg b/keama/tests/shareinshare.msg
new file mode 100644
index 00000000..a2579e8e
--- /dev/null
+++ b/keama/tests/shareinshare.msg
@@ -0,0 +1 @@
+shareinshare.err line 6: shared-network parameters not allowed here.
diff --git a/keama/tests/shareinsubnet4.err4 b/keama/tests/shareinsubnet4.err4
new file mode 100644
index 00000000..ecc0d080
--- /dev/null
+++ b/keama/tests/shareinsubnet4.err4
@@ -0,0 +1,10 @@
+# shared-network declaration inside DHCPv4 subnet declaration config
+
+# subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # can't put a shared-network declaration here
+ shared-network "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/shareinsubnet4.msg b/keama/tests/shareinsubnet4.msg
new file mode 100644
index 00000000..c332da87
--- /dev/null
+++ b/keama/tests/shareinsubnet4.msg
@@ -0,0 +1 @@
+shareinsubnet4.err4 line 6: shared-network parameters not allowed here.
diff --git a/keama/tests/shareinsubnet6.err6 b/keama/tests/shareinsubnet6.err6
new file mode 100644
index 00000000..fec6f6d2
--- /dev/null
+++ b/keama/tests/shareinsubnet6.err6
@@ -0,0 +1,10 @@
+# shared-network declaration inside DHCPv6 subnet declaration config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # can't put a shared-network declaration here
+ shared-network "illegal" {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/shareinsubnet6.msg b/keama/tests/shareinsubnet6.msg
new file mode 100644
index 00000000..640e5323
--- /dev/null
+++ b/keama/tests/shareinsubnet6.msg
@@ -0,0 +1 @@
+shareinsubnet6.err6 line 6: shared-network parameters not allowed here.
diff --git a/keama/tests/sharenoname.err b/keama/tests/sharenoname.err
new file mode 100644
index 00000000..854a1728
--- /dev/null
+++ b/keama/tests/sharenoname.err
@@ -0,0 +1,6 @@
+# bad (no name)shared-network declaration config
+
+# shared-network declaration
+shared-network {
+
+}
diff --git a/keama/tests/sharenoname.msg b/keama/tests/sharenoname.msg
new file mode 100644
index 00000000..ad12f0d7
--- /dev/null
+++ b/keama/tests/sharenoname.msg
@@ -0,0 +1 @@
+sharenoname.err line 4: expecting a name for shared-network
diff --git a/keama/tests/shareone4.in4 b/keama/tests/shareone4.in4
new file mode 100644
index 00000000..ef0e15ac
--- /dev/null
+++ b/keama/tests/shareone4.in4
@@ -0,0 +1,22 @@
+# DHCPv4 one-subnet shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ # interface
+ interface "en0";
+ # option
+ option domain-search "example.com", "example.org";
+ # parameter
+ default-lease-time 1800;
+ # subnet declaration
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ # redefined parameter
+ default-lease-time 3600;
+ # another option
+ option ip-forwarding true;
+ }
+ # pool (must be after the subnet)
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+}
diff --git a/keama/tests/shareone4.out b/keama/tests/shareone4.out
new file mode 100644
index 00000000..56f5cbb7
--- /dev/null
+++ b/keama/tests/shareone4.out
@@ -0,0 +1,44 @@
+{
+ # DHCPv4 one-subnet shared-network declaration config
+ # shared-network declaration
+ "Dhcp4": {
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ "subnet4": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "valid-lifetime": 3600,
+ "option-data": [
+ # another option
+ {
+ "space": "dhcp4",
+ "name": "ip-forwarding",
+ "code": 19,
+ "data": "true"
+ },
+ # interface
+ # option
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "interface": "en0",
+ "pools": [
+ # pool (must be after the subnet)
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/shareone6.in6 b/keama/tests/shareone6.in6
new file mode 100644
index 00000000..11b03cb0
--- /dev/null
+++ b/keama/tests/shareone6.in6
@@ -0,0 +1,19 @@
+# DHCPv6 one-subnet shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ # interface
+ interface "en0";
+ # option
+ option dhcp6.domain-search "example.com", "example.org";
+ # parameter
+ default-lease-time 1800;
+ # subnet declaration
+ subnet6 2001::/64 {
+ # redefined parameter
+ default-lease-time 3600;
+ # pool
+ range6 2001::1000 2001::2000;
+ }
+ # tried another pool here but DHCPv6 pools are allowed only in subnets
+}
diff --git a/keama/tests/shareone6.out b/keama/tests/shareone6.out
new file mode 100644
index 00000000..6f8389c3
--- /dev/null
+++ b/keama/tests/shareone6.out
@@ -0,0 +1,37 @@
+{
+ # DHCPv6 one-subnet shared-network declaration config
+ # shared-network declaration
+ "Dhcp6": {
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ "subnet6": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "valid-lifetime": 3600,
+ "pools": [
+ {
+ # pool
+ "pool": "2001::1000 - 2001::2000"
+ }
+ ],
+ "interface": "en0",
+ "option-data": [
+ # interface
+ # option
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/sharepools4.in4 b/keama/tests/sharepools4.in4
new file mode 100644
index 00000000..b42a8481
--- /dev/null
+++ b/keama/tests/sharepools4.in4
@@ -0,0 +1,27 @@
+# DHCPv4 two pools and subnets shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ # interface
+ interface "en0";
+ # option
+ option domain-search "example.com", "example.org";
+ # parameter
+ default-lease-time 1800;
+ # subnet declaration
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ # redefined parameter
+ default-lease-time 3600;
+ # another option
+ option ip-forwarding true;
+ }
+ # second subnet declaration
+ subnet 10.10.10.0 netmask 255.255.255.224 { }
+ # pools at shared-network level
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+ pool {
+ range 10.10.10.5 10.10.10.10;
+ }
+}
diff --git a/keama/tests/sharepools4.out b/keama/tests/sharepools4.out
new file mode 100644
index 00000000..087ec5c8
--- /dev/null
+++ b/keama/tests/sharepools4.out
@@ -0,0 +1,63 @@
+{
+ # DHCPv4 two pools and subnets shared-network declaration config
+ # shared-network declaration
+ "Dhcp4": {
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ /// Kea shared-networks are different, cf Kea #236
+ "shared-networks": [
+ {
+ "name": "foobar",
+ "subnet4": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "valid-lifetime": 3600,
+ "option-data": [
+ # another option
+ {
+ "space": "dhcp4",
+ "name": "ip-forwarding",
+ "code": 19,
+ "data": "true"
+ }
+ ],
+ "pools": [
+ # pools at shared-network level
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ },
+ # second subnet declaration
+ {
+ "id": 2,
+ "subnet": "10.10.10.0/27",
+ "pools": [
+ {
+ "pool": "10.10.10.5 - 10.10.10.10"
+ }
+ ]
+ }
+ ],
+ "interface": "en0",
+ "option-data": [
+ # interface
+ # option
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800
+ }
+ ]
+ }
+}
diff --git a/keama/tests/sharetwo4.in4 b/keama/tests/sharetwo4.in4
new file mode 100644
index 00000000..fa9126fe
--- /dev/null
+++ b/keama/tests/sharetwo4.in4
@@ -0,0 +1,29 @@
+# DHCPv4 two subnets in shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ # interface
+ interface "en0";
+ # option
+ option domain-search "example.com", "example.org";
+ # parameter
+ default-lease-time 1800;
+ # subnet declaration
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ # redefined parameter
+ default-lease-time 3600;
+ # another option
+ option ip-forwarding true;
+ # pool inside the subnet
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+ }
+ # second subnet declaration
+ subnet 10.10.10.0 netmask 255.255.255.224 {
+ # pool inside the subnet
+ pool {
+ range 10.10.10.5 10.10.10.10;
+ }
+ }
+}
diff --git a/keama/tests/sharetwo4.out b/keama/tests/sharetwo4.out
new file mode 100644
index 00000000..71f7832e
--- /dev/null
+++ b/keama/tests/sharetwo4.out
@@ -0,0 +1,64 @@
+{
+ # DHCPv4 two subnets in shared-network declaration config
+ # shared-network declaration
+ "Dhcp4": {
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ /// Kea shared-networks are different, cf Kea #236
+ "shared-networks": [
+ {
+ "name": "foobar",
+ "subnet4": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "valid-lifetime": 3600,
+ "option-data": [
+ # another option
+ {
+ "space": "dhcp4",
+ "name": "ip-forwarding",
+ "code": 19,
+ "data": "true"
+ }
+ ],
+ "pools": [
+ # pool inside the subnet
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ]
+ },
+ # second subnet declaration
+ {
+ "id": 2,
+ "subnet": "10.10.10.0/27",
+ "pools": [
+ # pool inside the subnet
+ {
+ "pool": "10.10.10.5 - 10.10.10.10"
+ }
+ ]
+ }
+ ],
+ "interface": "en0",
+ "option-data": [
+ # interface
+ # option
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800
+ }
+ ]
+ }
+}
diff --git a/keama/tests/sharetwo6.in6 b/keama/tests/sharetwo6.in6
new file mode 100644
index 00000000..3c75aad5
--- /dev/null
+++ b/keama/tests/sharetwo6.in6
@@ -0,0 +1,24 @@
+# DHCPv6 two subnets in shared-network declaration config
+
+# shared-network declaration
+shared-network "foobar" {
+ # interface
+ interface "en0";
+ # option
+ option dhcp6.domain-search "example.com", "example.org";
+ # parameter
+ default-lease-time 1800;
+ # subnet declaration
+ subnet6 2001::/64 {
+ # redefined parameter
+ default-lease-time 3600;
+ # pool
+ range6 2001::1000 2001::2000;
+ }
+ # second subnet declaration
+ subnet6 2002::/64 {
+ pool6 {
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: /64;
+ }
+ }
+}
diff --git a/keama/tests/sharetwo6.out b/keama/tests/sharetwo6.out
new file mode 100644
index 00000000..23df4e7c
--- /dev/null
+++ b/keama/tests/sharetwo6.out
@@ -0,0 +1,56 @@
+{
+ # DHCPv6 two subnets in shared-network declaration config
+ # shared-network declaration
+ "Dhcp6": {
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ },
+ /// Kea shared-networks are different, cf Kea #236
+ "shared-networks": [
+ {
+ "name": "foobar",
+ "subnet6": [
+ # subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "valid-lifetime": 3600,
+ "pools": [
+ {
+ # pool
+ "pool": "2001::1000 - 2001::2000"
+ }
+ ]
+ },
+ # second subnet declaration
+ {
+ "id": 2,
+ "subnet": "2002::/64",
+ "pd-pools": [
+ {
+ "prefix": "2001:0:0:10::",
+ "delegated-len": 64,
+ "prefix-len": 60
+ }
+ ]
+ }
+ ],
+ "interface": "en0",
+ "option-data": [
+ # interface
+ # option
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800
+ }
+ ]
+ }
+}
diff --git a/keama/tests/sname4.notyet b/keama/tests/sname4.notyet
new file mode 100644
index 00000000..172b2acf
--- /dev/null
+++ b/keama/tests/sname4.notyet
@@ -0,0 +1,20 @@
+# server-name data expression
+# Kea has no server-name extractor in libeval
+
+# authoritative is mandatory
+authoritative;
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# by filename superclass
+class "byfn" {
+ match server-name;
+}
+
+subclass "byfn" "foobar" {
+ option domain-name-servers 10.5.5.1;
+}
+
+# raw
+option bootfile-name = concat(server-name, "/", option host-name);
diff --git a/keama/tests/spawning6.in6 b/keama/tests/spawning6.in6
new file mode 100644
index 00000000..0c33afe1
--- /dev/null
+++ b/keama/tests/spawning6.in6
@@ -0,0 +1,11 @@
+# spawning declaration config
+
+# options
+option dhcp6.mysystem code 1250 = text;
+option dhcp6.myversion code 1251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ spawn with option dhcp6.mysystem;
+ option dhcp6.myversion 1;
+}
diff --git a/keama/tests/spawning6.out b/keama/tests/spawning6.out
new file mode 100644
index 00000000..ce556d80
--- /dev/null
+++ b/keama/tests/spawning6.out
@@ -0,0 +1,37 @@
+{
+ # spawning declaration config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "mysystem",
+ "code": 1250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// Spawning classes are not supported by Kea
+ /// Reference Kea #248
+ /// spawn with: option dhcp6.mysystem
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subclass4.in4 b/keama/tests/subclass4.in4
new file mode 100644
index 00000000..bdae6632
--- /dev/null
+++ b/keama/tests/subclass4.in4
@@ -0,0 +1,23 @@
+# subclass declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ match option mysystem;
+ option myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" "version1";
+
+# option setting subclass declaration
+subclass "foobar" "version2" { option myversion 2; }
+
+# complex subclass declaration
+subclass "foobar" "version3" {
+ option myversion 3;
+ next-server 192.168.0.1;
+}
diff --git a/keama/tests/subclass4.out b/keama/tests/subclass4.out
new file mode 100644
index 00000000..e155d0de
--- /dev/null
+++ b/keama/tests/subclass4.out
@@ -0,0 +1,84 @@
+{
+ # subclass declaration config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "mysystem",
+ "code": 250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp.mysystem
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 'version1'
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version1'
+ "test": "option[250].hex == 'version1'"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'version2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "2"
+ }
+ ],
+ /// from: match option dhcp.mysystem
+ /// data: 'version2'
+ "test": "option[250].hex == 'version2'"
+ },
+ # complex subclass declaration
+ /// subclass selector 'version3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "3"
+ }
+ ],
+ "next-server": "192.168.0.1",
+ /// from: match option dhcp.mysystem
+ /// data: 'version3'
+ "test": "option[250].hex == 'version3'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subclass6.in6 b/keama/tests/subclass6.in6
new file mode 100644
index 00000000..41408180
--- /dev/null
+++ b/keama/tests/subclass6.in6
@@ -0,0 +1,23 @@
+# subclass declaration config
+
+# options
+option dhcp6.mysystem code 1250 = text;
+option dhcp6.myversion code 1251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ match option dhcp6.mysystem;
+ option dhcp6.myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" "version1";
+
+# option setting subclass declaration
+subclass "foobar" "version2" { option dhcp6.myversion 2; }
+
+# complex subclass declaration
+subclass "foobar" "version3" {
+ option dhcp6.myversion 3;
+ option dhcp6.rapid-commit;
+}
diff --git a/keama/tests/subclass6.out b/keama/tests/subclass6.out
new file mode 100644
index 00000000..3828d58d
--- /dev/null
+++ b/keama/tests/subclass6.out
@@ -0,0 +1,89 @@
+{
+ # subclass declaration config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "mysystem",
+ "code": 1250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp6.mysystem
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 'version1'
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version1'
+ "test": "option[1250].hex == 'version1'"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'version2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "2"
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version2'
+ "test": "option[1250].hex == 'version2'"
+ },
+ # complex subclass declaration
+ /// subclass selector 'version3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "3"
+ },
+ {
+ "space": "dhcp6",
+ "name": "rapid-commit",
+ "code": 14,
+ "data": ""
+ }
+ ],
+ /// from: match option dhcp6.mysystem
+ /// data: 'version3'
+ "test": "option[1250].hex == 'version3'"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subclassbinsel4.in4 b/keama/tests/subclassbinsel4.in4
new file mode 100644
index 00000000..95d5aa54
--- /dev/null
+++ b/keama/tests/subclassbinsel4.in4
@@ -0,0 +1,16 @@
+# subclass declaration config
+
+# options
+option myversion code 251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ match hardware;
+ option myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" 1:00:07:0E:36:48:19;
+
+# option setting subclass declaration
+subclass "foobar" 1:00:0B:FD:32:E6:FA { option myversion 2; }
diff --git a/keama/tests/subclassbinsel4.out b/keama/tests/subclassbinsel4.out
new file mode 100644
index 00000000..589afcb8
--- /dev/null
+++ b/keama/tests/subclassbinsel4.out
@@ -0,0 +1,61 @@
+{
+ # subclass declaration config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: hardware
+ {
+ "name": "foobar",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 0x0x0100070e364819
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "1"
+ }
+ ],
+ /// from: match hardware
+ /// data: 0x0100070e364819
+ "test": "concat(substring(pkt4.htype,-1,all), pkt4.mac) == 0x0100070e364819"
+ },
+ # option setting subclass declaration
+ /// subclass selector 0x0x01000bfd32e6fa
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "data": "2"
+ }
+ ],
+ /// from: match hardware
+ /// data: 0x01000bfd32e6fa
+ "test": "concat(substring(pkt4.htype,-1,all), pkt4.mac) == 0x01000bfd32e6fa"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subclassbinsel6.in6 b/keama/tests/subclassbinsel6.in6
new file mode 100644
index 00000000..0a7e36d7
--- /dev/null
+++ b/keama/tests/subclassbinsel6.in6
@@ -0,0 +1,25 @@
+# subclass declaration config
+
+# options
+option dhcp6.hardware code 1250 = string;
+option dhcp6.myversion code 1251 = unsigned integer 16;
+
+# superclass declaration
+class "foobar" {
+ # no harware in DHCPv6
+ match option dhcp6.hardware;
+ option dhcp6.myversion 1;
+}
+
+# simple subclass declaration
+subclass "foobar" 1:00:07:0E:36:48:19;
+
+# option setting subclass declaration
+subclass "foobar" 1:00:0B:FD:32:E6:FA { option dhcp6.myversion 2; }
+
+# complex subclass declaration
+subclass "foobar" 1:00:02:B3:88:C5:27 {
+ option dhcp6.myversion 3;
+ lease limit 20;
+}
+
diff --git a/keama/tests/subclassbinsel6.out b/keama/tests/subclassbinsel6.out
new file mode 100644
index 00000000..42c96bb2
--- /dev/null
+++ b/keama/tests/subclassbinsel6.out
@@ -0,0 +1,88 @@
+{
+ # subclass declaration config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "hardware",
+ "code": 1250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "type": "uint16"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp6.hardware
+ {
+ "name": "foobar",
+ "option-data": [
+ # no harware in DHCPv6
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ]
+ },
+ # simple subclass declaration
+ /// subclass selector 0x0x0100070e364819
+ {
+ "name": "sub#foobar#0",
+ "option-data": [
+ # no harware in DHCPv6
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "1"
+ }
+ ],
+ /// from: match option dhcp6.hardware
+ /// data: 0x0100070e364819
+ "test": "option[1250].hex == 0x0100070e364819"
+ },
+ # option setting subclass declaration
+ /// subclass selector 0x0x01000bfd32e6fa
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "2"
+ }
+ ],
+ /// from: match option dhcp6.hardware
+ /// data: 0x01000bfd32e6fa
+ "test": "option[1250].hex == 0x01000bfd32e6fa"
+ },
+ # complex subclass declaration
+ /// subclass selector 0x0x010002b388c527
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "data": "3"
+ }
+ ],
+// /// Per-class limit is not supported by Kea
+// /// Reference Kea #237
+// "lease-limit": 20,
+ /// from: match option dhcp6.hardware
+ /// data: 0x010002b388c527
+ "test": "option[1250].hex == 0x010002b388c527"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subclassguard4.in4 b/keama/tests/subclassguard4.in4
new file mode 100644
index 00000000..9a22d356
--- /dev/null
+++ b/keama/tests/subclassguard4.in4
@@ -0,0 +1,24 @@
+# subclass with guard declaration config
+
+# options
+option mysystem code 250 = text;
+option myversion code 251 = unsigned integer 16;
+option mydescr code 252 = text;
+
+# superclass declaration
+class "foobar" {
+ match if option myversion = 0:1;
+ match option mysystem;
+}
+
+# simple subclass declaration
+subclass "foobar" "system1";
+
+# option setting subclass declaration
+subclass "foobar" "system2" { option mydescr "1.2"; }
+
+# complex subclass declaration
+subclass "foobar" "system3" {
+ option mydescr "1.3";
+ next-server 192.168.0.1;
+}
diff --git a/keama/tests/subclassguard4.out b/keama/tests/subclassguard4.out
new file mode 100644
index 00000000..910b5b93
--- /dev/null
+++ b/keama/tests/subclassguard4.out
@@ -0,0 +1,79 @@
+{
+ # subclass with guard declaration config
+ # options
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "dhcp4",
+ "name": "mysystem",
+ "code": 250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp4",
+ "name": "myversion",
+ "code": 251,
+ "type": "uint16"
+ },
+ {
+ "space": "dhcp4",
+ "name": "mydescr",
+ "code": 252,
+ "type": "string"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp.mysystem
+ {
+ "name": "foobar",
+ /// from: match if (option dhcp.myversion) = 0x0001
+ "test": "option[251].hex == 0x0001"
+ },
+ # simple subclass declaration
+ /// subclass selector 'system1'
+ {
+ "name": "sub#foobar#0",
+ /// from: match-if (option dhcp.myversion) = 0x0001
+ /// match: option dhcp.mysystem
+ /// data: 'system1'
+ "test": "(option[251].hex == 0x0001) and (option[250].hex == 'system1')"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'system2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "mydescr",
+ "code": 252,
+ "data": "1.2"
+ }
+ ],
+ /// from: match-if (option dhcp.myversion) = 0x0001
+ /// match: option dhcp.mysystem
+ /// data: 'system2'
+ "test": "(option[251].hex == 0x0001) and (option[250].hex == 'system2')"
+ },
+ # complex subclass declaration
+ /// subclass selector 'system3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "mydescr",
+ "code": 252,
+ "data": "1.3"
+ }
+ ],
+ "next-server": "192.168.0.1",
+ /// from: match-if (option dhcp.myversion) = 0x0001
+ /// match: option dhcp.mysystem
+ /// data: 'system3'
+ "test": "(option[251].hex == 0x0001) and (option[250].hex == 'system3')"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subclassguard6.in6 b/keama/tests/subclassguard6.in6
new file mode 100644
index 00000000..5c2119a6
--- /dev/null
+++ b/keama/tests/subclassguard6.in6
@@ -0,0 +1,24 @@
+# subclass with guard declaration config
+
+# options
+option dhcp6.mysystem code 1250 = text;
+option dhcp6.myversion code 1251 = unsigned integer 16;
+option dhcp6.mydescr code 1252 = text;
+
+# superclass declaration
+class "foobar" {
+ match if option dhcp6.myversion = 0:1;
+ match option dhcp6.mysystem;
+}
+
+# simple subclass declaration
+subclass "foobar" "system1";
+
+# option setting subclass declaration
+subclass "foobar" "system2" { option dhcp6.mydescr "1.2"; }
+
+# complex subclass declaration
+subclass "foobar" "system3" {
+ option dhcp6.mydescr "1.3";
+ option dhcp6.rapid-commit;
+}
diff --git a/keama/tests/subclassguard6.out b/keama/tests/subclassguard6.out
new file mode 100644
index 00000000..26a9d4dc
--- /dev/null
+++ b/keama/tests/subclassguard6.out
@@ -0,0 +1,84 @@
+{
+ # subclass with guard declaration config
+ # options
+ "Dhcp6": {
+ "option-def": [
+ {
+ "space": "dhcp6",
+ "name": "mysystem",
+ "code": 1250,
+ "type": "string"
+ },
+ {
+ "space": "dhcp6",
+ "name": "myversion",
+ "code": 1251,
+ "type": "uint16"
+ },
+ {
+ "space": "dhcp6",
+ "name": "mydescr",
+ "code": 1252,
+ "type": "string"
+ }
+ ],
+ "client-classes": [
+ # superclass declaration
+ /// match: option dhcp6.mysystem
+ {
+ "name": "foobar",
+ /// from: match if (option dhcp6.myversion) = 0x0001
+ "test": "option[1251].hex == 0x0001"
+ },
+ # simple subclass declaration
+ /// subclass selector 'system1'
+ {
+ "name": "sub#foobar#0",
+ /// from: match-if (option dhcp6.myversion) = 0x0001
+ /// match: option dhcp6.mysystem
+ /// data: 'system1'
+ "test": "(option[1251].hex == 0x0001) and (option[1250].hex == 'system1')"
+ },
+ # option setting subclass declaration
+ /// subclass selector 'system2'
+ {
+ "name": "sub#foobar#1",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "mydescr",
+ "code": 1252,
+ "data": "1.2"
+ }
+ ],
+ /// from: match-if (option dhcp6.myversion) = 0x0001
+ /// match: option dhcp6.mysystem
+ /// data: 'system2'
+ "test": "(option[1251].hex == 0x0001) and (option[1250].hex == 'system2')"
+ },
+ # complex subclass declaration
+ /// subclass selector 'system3'
+ {
+ "name": "sub#foobar#2",
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "mydescr",
+ "code": 1252,
+ "data": "1.3"
+ },
+ {
+ "space": "dhcp6",
+ "name": "rapid-commit",
+ "code": 14,
+ "data": ""
+ }
+ ],
+ /// from: match-if (option dhcp6.myversion) = 0x0001
+ /// match: option dhcp6.mysystem
+ /// data: 'system3'
+ "test": "(option[1251].hex == 0x0001) and (option[1250].hex == 'system3')"
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subnet4.in4 b/keama/tests/subnet4.in4
new file mode 100644
index 00000000..9c9247a4
--- /dev/null
+++ b/keama/tests/subnet4.in4
@@ -0,0 +1,16 @@
+# DHCPv4 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1800;
+
+# DHCPv4 subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # at least one pool is required
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+ option domain-search "example.com", "example.org";
+ default-lease-time 3600;
+ ignore-client-uids false;
+}
+
diff --git a/keama/tests/subnet4.out b/keama/tests/subnet4.out
new file mode 100644
index 00000000..2b50c272
--- /dev/null
+++ b/keama/tests/subnet4.out
@@ -0,0 +1,33 @@
+{
+ # DHCPv4 subnet declaration config
+ # parameter which will be changed in subnet
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "subnet4": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # at least one pool is required
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 3600,
+ "match-client-id": true
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subnet42if.err4 b/keama/tests/subnet42if.err4
new file mode 100644
index 00000000..b65c5d72
--- /dev/null
+++ b/keama/tests/subnet42if.err4
@@ -0,0 +1,8 @@
+# bad (2 interfaces) DHCPv4 subnet declaration config
+
+# DHCPv4 subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ interface "foo";
+ interface "bar";
+}
+
diff --git a/keama/tests/subnet42if.msg b/keama/tests/subnet42if.msg
new file mode 100644
index 00000000..22cd15dc
--- /dev/null
+++ b/keama/tests/subnet42if.msg
@@ -0,0 +1 @@
+subnet42if.err4 line 6: A subnet can't be connected to two interfaces.
diff --git a/keama/tests/subnet4auth.in4 b/keama/tests/subnet4auth.in4
new file mode 100644
index 00000000..dd7750d7
--- /dev/null
+++ b/keama/tests/subnet4auth.in4
@@ -0,0 +1,18 @@
+# DHCPv4 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1800;
+
+# DHCPv4 subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.224 {
+ # at least one pool is required
+ pool {
+ range 10.5.5.5 10.5.5.10;
+ }
+ # authorize here
+ authoritative;
+ option domain-search "example.com", "example.org";
+ default-lease-time 3600;
+ ignore-client-uids false;
+}
+
diff --git a/keama/tests/subnet4auth.out b/keama/tests/subnet4auth.out
new file mode 100644
index 00000000..ad605779
--- /dev/null
+++ b/keama/tests/subnet4auth.out
@@ -0,0 +1,35 @@
+{
+ # DHCPv4 subnet declaration config
+ # parameter which will be changed in subnet
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "subnet4": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "10.5.5.0/27",
+ "pools": [
+ # at least one pool is required
+ {
+ "pool": "10.5.5.5 - 10.5.5.10"
+ }
+ ],
+ # authorize here
+ "authoritative": true,
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 3600,
+ "match-client-id": true
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subnet4badmask.err4 b/keama/tests/subnet4badmask.err4
new file mode 100644
index 00000000..979f5cbb
--- /dev/null
+++ b/keama/tests/subnet4badmask.err4
@@ -0,0 +1,7 @@
+# bad (bad netmask) DHCPv4 subnet declaration config
+
+# DHCPv4 subnet declaration
+subnet 10.5.5.0 netmask 255.255.255.96 {
+ default-lease-time 1800;
+}
+
diff --git a/keama/tests/subnet4badmask.msg b/keama/tests/subnet4badmask.msg
new file mode 100644
index 00000000..860aec2d
--- /dev/null
+++ b/keama/tests/subnet4badmask.msg
@@ -0,0 +1 @@
+subnet4badmask.err4 line 4: can't get a prefix from 10.5.5.0 mask 255.255.255.96
diff --git a/keama/tests/subnet4inclass.err4 b/keama/tests/subnet4inclass.err4
new file mode 100644
index 00000000..51ede4b0
--- /dev/null
+++ b/keama/tests/subnet4inclass.err4
@@ -0,0 +1,10 @@
+# DHCPv4 subnet declaration inside class declaration config
+
+# class declaration
+class "foobar" {
+ # can't put a DHCPv4 subnet declaration here
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/subnet4inclass.msg b/keama/tests/subnet4inclass.msg
new file mode 100644
index 00000000..eabc9e47
--- /dev/null
+++ b/keama/tests/subnet4inclass.msg
@@ -0,0 +1 @@
+subnet4inclass.err4 line 6: subnet declarations not allowed here.
diff --git a/keama/tests/subnet4inhost.err4 b/keama/tests/subnet4inhost.err4
new file mode 100644
index 00000000..266e6dc3
--- /dev/null
+++ b/keama/tests/subnet4inhost.err4
@@ -0,0 +1,11 @@
+# DHCPv4 subnet declaration inside host declaration config
+
+# host declaration
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ # can't put a DHCPv4 subnet declaration here
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/subnet4inhost.msg b/keama/tests/subnet4inhost.msg
new file mode 100644
index 00000000..49e7d18d
--- /dev/null
+++ b/keama/tests/subnet4inhost.msg
@@ -0,0 +1 @@
+subnet4inhost.err4 line 7: subnet declarations not allowed here.
diff --git a/keama/tests/subnet4nomask.err4 b/keama/tests/subnet4nomask.err4
new file mode 100644
index 00000000..42266d03
--- /dev/null
+++ b/keama/tests/subnet4nomask.err4
@@ -0,0 +1,7 @@
+# bad (no netmask) DHCPv4 subnet declaration config
+
+# DHCPv4 subnet declaration
+subnet 10.5.5.0/27 {
+ default-lease-time 1800;
+}
+
diff --git a/keama/tests/subnet4nomask.msg b/keama/tests/subnet4nomask.msg
new file mode 100644
index 00000000..2d786c10
--- /dev/null
+++ b/keama/tests/subnet4nomask.msg
@@ -0,0 +1 @@
+subnet4nomask.err4 line 4: Expecting netmask
diff --git a/keama/tests/subnet6.in6 b/keama/tests/subnet6.in6
new file mode 100644
index 00000000..ec834fd3
--- /dev/null
+++ b/keama/tests/subnet6.in6
@@ -0,0 +1,18 @@
+# DHCPv6 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1800;
+
+# DHCPv4 subnet declaration
+subnet6 2001::/64 {
+ # at least one pool is required
+ pool6 {
+ range6 2001::100 2001::200;
+ }
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 3600;
+ pool6 {
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: /64;
+ }
+}
+
diff --git a/keama/tests/subnet6.out b/keama/tests/subnet6.out
new file mode 100644
index 00000000..f3535931
--- /dev/null
+++ b/keama/tests/subnet6.out
@@ -0,0 +1,39 @@
+{
+ # DHCPv6 subnet declaration config
+ # parameter which will be changed in subnet
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "subnet6": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ # at least one pool is required
+ {
+ "pool": "2001::100 - 2001::200"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 3600,
+ "pd-pools": [
+ {
+ "prefix": "2001:0:0:10::",
+ "delegated-len": 64,
+ "prefix-len": 60
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subnet62if.err6 b/keama/tests/subnet62if.err6
new file mode 100644
index 00000000..37fdc3f9
--- /dev/null
+++ b/keama/tests/subnet62if.err6
@@ -0,0 +1,8 @@
+# bad (2 interfaces) DHCPv6 subnet declaration config
+
+# DHCPv6 subnet declaration
+subnet6 2001::/64 {
+ interface "foo";
+ interface "bar";
+}
+
diff --git a/keama/tests/subnet62if.msg b/keama/tests/subnet62if.msg
new file mode 100644
index 00000000..66f6b900
--- /dev/null
+++ b/keama/tests/subnet62if.msg
@@ -0,0 +1 @@
+subnet62if.err6 line 6: A subnet can't be connected to two interfaces.
diff --git a/keama/tests/subnet6auth.in6 b/keama/tests/subnet6auth.in6
new file mode 100644
index 00000000..a41ff6f4
--- /dev/null
+++ b/keama/tests/subnet6auth.in6
@@ -0,0 +1,21 @@
+# DHCPv6 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1800;
+
+# DHCPv4 subnet declaration
+subnet6 2001::/64 {
+ # at least one pool is required
+ pool6 {
+ range6 2001::100 2001::200;
+ }
+ # authorize here
+ authoritative;
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 3600;
+ interface "en0";
+ pool6 {
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: /64;
+ }
+}
+
diff --git a/keama/tests/subnet6auth.out b/keama/tests/subnet6auth.out
new file mode 100644
index 00000000..aa79d1df
--- /dev/null
+++ b/keama/tests/subnet6auth.out
@@ -0,0 +1,44 @@
+{
+ # DHCPv6 subnet declaration config
+ # parameter which will be changed in subnet
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "subnet6": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pools": [
+ # at least one pool is required
+ {
+ "pool": "2001::100 - 2001::200"
+ }
+ ],
+ "option-data": [
+ # authorize here
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 3600,
+ "interface": "en0",
+ "pd-pools": [
+ {
+ "prefix": "2001:0:0:10::",
+ "delegated-len": 64,
+ "prefix-len": 60
+ }
+ ]
+ }
+ ],
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ }
+ }
+}
diff --git a/keama/tests/subnet6inclass.err6 b/keama/tests/subnet6inclass.err6
new file mode 100644
index 00000000..52368cd8
--- /dev/null
+++ b/keama/tests/subnet6inclass.err6
@@ -0,0 +1,10 @@
+# DHCPv6 subnet declaration inside class declaration config
+
+# class declaration
+class "foobar" {
+ # can't put a DHCPv6 subnet declaration here
+ subnet6 2001::/64 {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/subnet6inclass.msg b/keama/tests/subnet6inclass.msg
new file mode 100644
index 00000000..e7360029
--- /dev/null
+++ b/keama/tests/subnet6inclass.msg
@@ -0,0 +1 @@
+subnet6inclass.err6 line 6: subnet declarations not allowed here.
diff --git a/keama/tests/subnet6inhost.err6 b/keama/tests/subnet6inhost.err6
new file mode 100644
index 00000000..914decd6
--- /dev/null
+++ b/keama/tests/subnet6inhost.err6
@@ -0,0 +1,11 @@
+# DHCPv6 subnet declaration inside host declaration config
+
+# host declaration
+host foobar {
+ hardware ethernet 00:0B:FD:32:E6:FA;
+ # can't put a DHCPv6 subnet declaration here
+ subnet6 2001::/64 {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/subnet6inhost.msg b/keama/tests/subnet6inhost.msg
new file mode 100644
index 00000000..bd49b89f
--- /dev/null
+++ b/keama/tests/subnet6inhost.msg
@@ -0,0 +1 @@
+subnet6inhost.err6 line 7: subnet declarations not allowed here.
diff --git a/keama/tests/subnet6multi.in6 b/keama/tests/subnet6multi.in6
new file mode 100644
index 00000000..a9974ba0
--- /dev/null
+++ b/keama/tests/subnet6multi.in6
@@ -0,0 +1,19 @@
+# DHCPv6 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1800;
+
+# DHCPv4 subnet declaration
+subnet6 2001::/64 {
+ # at least one pool is required
+ pool6 {
+ # the pool is shared between addresses and prefixes
+ range6 2001::100 2001::200;
+ range6 2001::1000 2001::2000;
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: /64;
+ prefix6 2001:0:0:80:: 2001:0:0:ff:: /64;
+ }
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 3600;
+}
+
diff --git a/keama/tests/subnet6multi.out b/keama/tests/subnet6multi.out
new file mode 100644
index 00000000..9a4defb6
--- /dev/null
+++ b/keama/tests/subnet6multi.out
@@ -0,0 +1,49 @@
+{
+ # DHCPv6 subnet declaration config
+ # parameter which will be changed in subnet
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "subnet6": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pd-pools": [
+ {
+ "prefix": "2001:0:0:10::",
+ "delegated-len": 64,
+ "prefix-len": 60
+ },
+ # at least one pool is required
+ {
+ "prefix": "2001:0:0:80::",
+ "delegated-len": 64,
+ "prefix-len": 57
+ }
+ ],
+ "pools": [
+ {
+ # the pool is shared between addresses and prefixes
+ "pool": "2001::100 - 2001::200"
+ },
+ # at least one pool is required
+ {
+ "pool": "2001::1000 - 2001::2000"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 3600
+ }
+ ]
+ }
+}
diff --git a/keama/tests/subnet6nolen.err6 b/keama/tests/subnet6nolen.err6
new file mode 100644
index 00000000..1a71ac79
--- /dev/null
+++ b/keama/tests/subnet6nolen.err6
@@ -0,0 +1,7 @@
+# bad (no length) DHCPv6 subnet declaration config
+
+# DHCPv6 subnet declaration
+subnet6 2001::/ {
+ default-lease-time 1800;
+}
+
diff --git a/keama/tests/subnet6nolen.msg b/keama/tests/subnet6nolen.msg
new file mode 100644
index 00000000..cc36f0e1
--- /dev/null
+++ b/keama/tests/subnet6nolen.msg
@@ -0,0 +1 @@
+subnet6nolen.err6 line 4: Expecting a number.
diff --git a/keama/tests/subnet6noslash.err6 b/keama/tests/subnet6noslash.err6
new file mode 100644
index 00000000..2083eab6
--- /dev/null
+++ b/keama/tests/subnet6noslash.err6
@@ -0,0 +1,7 @@
+# bad (no /) DHCPv6 subnet declaration config
+
+# DHCPv6 subnet declaration
+subnet6 2001:: {
+ default-lease-time 1800;
+}
+
diff --git a/keama/tests/subnet6noslash.msg b/keama/tests/subnet6noslash.msg
new file mode 100644
index 00000000..63fa81c6
--- /dev/null
+++ b/keama/tests/subnet6noslash.msg
@@ -0,0 +1 @@
+subnet6noslash.err6 line 4: Expecting a '/'.
diff --git a/keama/tests/subnet6one.in6 b/keama/tests/subnet6one.in6
new file mode 100644
index 00000000..7c0c3a0b
--- /dev/null
+++ b/keama/tests/subnet6one.in6
@@ -0,0 +1,18 @@
+# DHCPv6 subnet declaration config
+
+# parameter which will be changed in subnet
+default-lease-time 1800;
+
+# DHCPv4 subnet declaration
+subnet6 2001::/64 {
+ # at least one pool is required
+ pool6 {
+ # the pool is shared between addresses and prefixes
+ range6 2001::100 2001::200;
+ prefix6 2001:0:0:10:: 2001:0:0:1f:: /64;
+ }
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 3600;
+ interface "en0";
+}
+
diff --git a/keama/tests/subnet6one.out b/keama/tests/subnet6one.out
new file mode 100644
index 00000000..e1388c81
--- /dev/null
+++ b/keama/tests/subnet6one.out
@@ -0,0 +1,45 @@
+{
+ # DHCPv6 subnet declaration config
+ # parameter which will be changed in subnet
+ "Dhcp6": {
+ "valid-lifetime": 1800,
+ "subnet6": [
+ # DHCPv4 subnet declaration
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "pd-pools": [
+ # at least one pool is required
+ {
+ "prefix": "2001:0:0:10::",
+ "delegated-len": 64,
+ "prefix-len": 60
+ }
+ ],
+ "pools": [
+ # at least one pool is required
+ {
+ # the pool is shared between addresses and prefixes
+ "pool": "2001::100 - 2001::200"
+ }
+ ],
+ "option-data": [
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 3600,
+ "interface": "en0"
+ }
+ ],
+ "interfaces-config": {
+ "interfaces": [
+ "en0"
+ ]
+ }
+ }
+}
diff --git a/keama/tests/subnetinsubnet4.err4 b/keama/tests/subnetinsubnet4.err4
new file mode 100644
index 00000000..c326c16d
--- /dev/null
+++ b/keama/tests/subnetinsubnet4.err4
@@ -0,0 +1,10 @@
+# DHCPv4 subnet declaration inside another subnet declaration config
+
+# DHCPv4 subnet declaration
+subnet 10.254.239.32 netmask 255.255.255.224 {
+ # can't put another subnet declaration here
+ subnet 10.5.5.0 netmask 255.255.255.224 {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/subnetinsubnet4.msg b/keama/tests/subnetinsubnet4.msg
new file mode 100644
index 00000000..710cffa7
--- /dev/null
+++ b/keama/tests/subnetinsubnet4.msg
@@ -0,0 +1 @@
+subnetinsubnet4.err4 line 6: subnet declarations not allowed here.
diff --git a/keama/tests/subnetinsubnet6.err6 b/keama/tests/subnetinsubnet6.err6
new file mode 100644
index 00000000..ac9a6097
--- /dev/null
+++ b/keama/tests/subnetinsubnet6.err6
@@ -0,0 +1,10 @@
+# DHCPv6 subnet declaration inside another subnet declaration config
+
+# DHCPv6 subnet declaration
+subnet6 2001:2::/64 {
+ # can't put another subnet declaration here
+ subnet6 2001::/64 {
+ default-lease-time 1800;
+ }
+}
+
diff --git a/keama/tests/subnetinsubnet6.msg b/keama/tests/subnetinsubnet6.msg
new file mode 100644
index 00000000..27f8f3fa
--- /dev/null
+++ b/keama/tests/subnetinsubnet6.msg
@@ -0,0 +1 @@
+subnetinsubnet6.err6 line 6: subnet declarations not allowed here.
diff --git a/keama/tests/substringdx4.in4 b/keama/tests/substringdx4.in4
new file mode 100644
index 00000000..ed0c9d35
--- /dev/null
+++ b/keama/tests/substringdx4.in4
@@ -0,0 +1,21 @@
+# substring data expression
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# use substring in a reductible match
+class "reductible" {
+ match substring(option host-name, 0, 3);
+}
+
+subclass "reductible" "www" { }
+
+# reduce literals too
+class "literal" {
+ match if option host-name = substring("www.example.com", 0, 3);
+}
+
+# raw
+option domain-name = substring(option domain-name, 4, 1000);
+
+
diff --git a/keama/tests/substringdx4.out b/keama/tests/substringdx4.out
new file mode 100644
index 00000000..75865424
--- /dev/null
+++ b/keama/tests/substringdx4.out
@@ -0,0 +1,49 @@
+{
+ # substring data expression
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # use substring in a reductible match
+ /// match: substring(option dhcp.host-name, 0, 3)
+ {
+ "name": "reductible"
+ },
+ /// subclass selector 'www'
+ {
+ "name": "sub#reductible#0",
+ /// from: match substring(option dhcp.host-name, 0, 3)
+ /// data: 'www'
+ "test": "substring(option[12].hex,0,3) == 'www'"
+ },
+ # reduce literals too
+ {
+ "name": "literal",
+ /// from: match if (option dhcp.host-name) = (substring('www.example.com', 0, 3))
+ "test": "option[12].hex == 'www'"
+ }
+ ],
+ "option-data": [
+// # raw
+// {
+// "space": "dhcp4",
+// "name": "domain-name",
+// "code": 15,
+// "csv-format": false,
+// "expression": {
+// "substring": {
+// "expression": {
+// "option": {
+// "universe": "dhcp",
+// "name": "domain-name",
+// "code": 15
+// }
+// },
+// "offset": 4,
+// "length": 1000
+// }
+// }
+// }
+ ]
+ }
+}
diff --git a/keama/tests/suffixdx4.in4 b/keama/tests/suffixdx4.in4
new file mode 100644
index 00000000..fc692d10
--- /dev/null
+++ b/keama/tests/suffixdx4.in4
@@ -0,0 +1,26 @@
+# suffix data expression
+# in fact ISC DHCP suffix can be reduced into Kea substring
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# use suffix in a reductible match
+class "reductible" {
+ match suffix(option host-name, 3);
+}
+
+subclass "reductible" "com" {
+ option domain-search "example.com";
+}
+
+subclass "reductible" "org" {
+ option domain-search "example.org";
+}
+
+# reduce literals too
+class "literal" {
+ match if option domain-name = suffix("www.example.com", 3);
+}
+
+# raw
+option domain-name = suffix(option domain-name, 3);
diff --git a/keama/tests/suffixdx4.out b/keama/tests/suffixdx4.out
new file mode 100644
index 00000000..12f045d6
--- /dev/null
+++ b/keama/tests/suffixdx4.out
@@ -0,0 +1,74 @@
+{
+ # suffix data expression
+ # in fact ISC DHCP suffix can be reduced into Kea substring
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800,
+ "client-classes": [
+ # use suffix in a reductible match
+ /// match: suffix(option dhcp.host-name, 3)
+ {
+ "name": "reductible"
+ },
+ /// subclass selector 'com'
+ {
+ "name": "sub#reductible#0",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.com\"",
+ "data": "example.com"
+ }
+ ],
+ /// from: match suffix(option dhcp.host-name, 3)
+ /// data: 'com'
+ "test": "substring(option[12].hex,-3,all) == 'com'"
+ },
+ /// subclass selector 'org'
+ {
+ "name": "sub#reductible#1",
+ "option-data": [
+ {
+ "space": "dhcp4",
+ "name": "domain-search",
+ "code": 119,
+// "original-data": "\"example.org\"",
+ "data": "example.org"
+ }
+ ],
+ /// from: match suffix(option dhcp.host-name, 3)
+ /// data: 'org'
+ "test": "substring(option[12].hex,-3,all) == 'org'"
+ },
+ # reduce literals too
+ {
+ "name": "literal",
+ /// from: match if (option dhcp.domain-name) = (suffix('www.example.com', 3))
+ "test": "option[15].hex == '.example.com'"
+ }
+ ],
+ "option-data": [
+// # raw
+// {
+// "space": "dhcp4",
+// "name": "domain-name",
+// "code": 15,
+// "csv-format": false,
+// "expression": {
+// "suffix": {
+// "expression": {
+// "option": {
+// "universe": "dhcp",
+// "name": "domain-name",
+// "code": 15
+// }
+// },
+// "length": 3
+// }
+// }
+// }
+ ]
+ }
+}
diff --git a/keama/tests/switchxsc4.in4 b/keama/tests/switchxsc4.in4
new file mode 100644
index 00000000..7ef6f2f3
--- /dev/null
+++ b/keama/tests/switchxsc4.in4
@@ -0,0 +1,18 @@
+# switch executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# a switch
+switch (option user-class) {
+case "accounting":
+ add "acct";
+ send ip-forwarding false;
+ default-lease-time 3600;
+ break;
+case "engineering":
+ allow booting;
+ log (debug, option host-name);
+ set foo = "bar";
+ break;
+}
diff --git a/keama/tests/switchxsc4.out b/keama/tests/switchxsc4.out
new file mode 100644
index 00000000..e45421d3
--- /dev/null
+++ b/keama/tests/switchxsc4.out
@@ -0,0 +1,79 @@
+{
+ # switch executable statement construct
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// # a switch
+// "statement": {
+// "switch": {
+// "condition": {
+// "option": {
+// "universe": "dhcp",
+// "name": "user-class",
+// "code": 77
+// }
+// },
+// "body": [
+// {
+// "case": "accounting"
+// },
+// {
+// "add-class": "acct"
+// },
+// {
+// /// Kea does not support option data set variants (send)
+// "option": {
+// "space": "dhcp4",
+// "name": "ip-forwarding",
+// "code": 19,
+// "data": "false"
+// }
+// },
+// {
+// "config": {
+// "name": "default-lease-time",
+// "code": 1,
+// "value": 3600
+// }
+// },
+// {
+// "break": null
+// },
+// {
+// "case": "engineering"
+// },
+// {
+// "config": {
+// "value": "allow",
+// "name": "allow-booting",
+// "code": 9
+// }
+// },
+// {
+// /// Kea does not support yet log statements
+// /// Reference Kea #234
+// "log": {
+// "priority": "debug",
+// "message": {
+// "option": {
+// "universe": "dhcp",
+// "name": "host-name",
+// "code": 12
+// }
+// }
+// }
+// },
+// {
+// "set": {
+// "name": "foo",
+// "value": "bar"
+// }
+// },
+// {
+// "break": null
+// }
+// ]
+// }
+// }
+ }
+}
diff --git a/keama/tests/switchxsc6.in6 b/keama/tests/switchxsc6.in6
new file mode 100644
index 00000000..a9c74f86
--- /dev/null
+++ b/keama/tests/switchxsc6.in6
@@ -0,0 +1,18 @@
+# switch executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# a switch
+switch (option dhcp6.remote-id) {
+case "accounting":
+ default dhcp6.bootfile-url foobar;
+ default-lease-time 3600;
+ unset foo;
+ break;
+case "engineering":
+ deny declines;
+ log (debug, "hello");
+ define foo (x) { return "world"; }
+ break;
+}
diff --git a/keama/tests/switchxsc6.out b/keama/tests/switchxsc6.out
new file mode 100644
index 00000000..b7fbd06c
--- /dev/null
+++ b/keama/tests/switchxsc6.out
@@ -0,0 +1,82 @@
+{
+ # switch executable statement construct
+ # empty configs are not accepted by Kea
+ "Dhcp6": {
+ "valid-lifetime": 1800
+// # a switch
+// "statement": {
+// "switch": {
+// "condition": {
+// "option": {
+// "universe": "dhcp6",
+// "name": "remote-id",
+// "code": 37
+// }
+// },
+// "body": [
+// {
+// "case": "accounting"
+// },
+// {
+// /// Kea does not support option data set variants (default)
+// "option": {
+// "space": "dhcp6",
+// "name": "bootfile-url",
+// "code": 59,
+// "data": "foobar"
+// }
+// },
+// {
+// "config": {
+// "name": "default-lease-time",
+// "code": 1,
+// "value": 3600
+// }
+// },
+// {
+// "unset": {
+// "name": "foo"
+// }
+// },
+// {
+// "break": null
+// },
+// {
+// "case": "engineering"
+// },
+// {
+// "config": {
+// "value": "deny",
+// "name": "declines",
+// "code": 29
+// }
+// },
+// {
+// /// Kea does not support yet log statements
+// /// Reference Kea #234
+// "log": {
+// "priority": "debug",
+// "message": "hello"
+// }
+// },
+// {
+// "define": {
+// "name": "foo",
+// "function": {
+// "arguments": "x",
+// "body": [
+// {
+// "return": "world"
+// }
+// ]
+// }
+// }
+// },
+// {
+// "break": null
+// }
+// ]
+// }
+// }
+ }
+}
diff --git a/keama/tests/tautology.err b/keama/tests/tautology.err
new file mode 100644
index 00000000..e1f506dd
--- /dev/null
+++ b/keama/tests/tautology.err
@@ -0,0 +1,9 @@
+# bad (tautology) class declaration config
+
+# class declaration
+class "tautology" {
+ # tautology
+ # note that true does not work as it is a variable reference
+ # and for the same reason quotes are needed (or one can use hexa)
+ match if "foo" = "foo";
+}
diff --git a/keama/tests/tautology.msg b/keama/tests/tautology.msg
new file mode 100644
index 00000000..80bf2feb
--- /dev/null
+++ b/keama/tests/tautology.msg
@@ -0,0 +1 @@
+tautology.err line 8: 'match if' with a constant boolean expression 'foo' = 'foo'
diff --git a/keama/tests/tautologyhexa.err b/keama/tests/tautologyhexa.err
new file mode 100644
index 00000000..69249d86
--- /dev/null
+++ b/keama/tests/tautologyhexa.err
@@ -0,0 +1,9 @@
+# bad (tautology) class declaration config
+
+# class declaration
+class "tautology" {
+ # tautology
+ # note that true does not work as it is a variable reference
+ # and for the same reason quotes are needed (or one can use hexa)
+ match if 12:34 = 56:78:9a;
+}
diff --git a/keama/tests/tautologyhexa.msg b/keama/tests/tautologyhexa.msg
new file mode 100644
index 00000000..7482482b
--- /dev/null
+++ b/keama/tests/tautologyhexa.msg
@@ -0,0 +1 @@
+tautologyhexa.err line 8: 'match if' with a constant boolean expression 0x1234 = 0x56789a
diff --git a/keama/tests/tautologysub.err b/keama/tests/tautologysub.err
new file mode 100644
index 00000000..08de2575
--- /dev/null
+++ b/keama/tests/tautologysub.err
@@ -0,0 +1,9 @@
+# bad (tautology) class declaration config
+
+# superclass declaration
+class "constant" {
+ match "foo";
+}
+
+# subclass declaration
+subclass "constant" "bar";
diff --git a/keama/tests/tautologysub.msg b/keama/tests/tautologysub.msg
new file mode 100644
index 00000000..d30f39a7
--- /dev/null
+++ b/keama/tests/tautologysub.msg
@@ -0,0 +1 @@
+tautologysub.err line 9: class matching rule evaluated to a constant boolean expression: 'foo' = 'bar'
diff --git a/keama/tests/temporary6.in6 b/keama/tests/temporary6.in6
new file mode 100644
index 00000000..dec7d99b
--- /dev/null
+++ b/keama/tests/temporary6.in6
@@ -0,0 +1,10 @@
+# DHCPv6 temporary (aka IA_TA) range config
+
+# subnet declaration
+subnet6 2001::/64 {
+ # range declaration
+ option dhcp6.domain-search "example.com", "example.org";
+ default-lease-time 1800;
+ range6 2001::100 temporary;
+ range6 2001::1000/116 temporary;
+}
diff --git a/keama/tests/temporary6.out b/keama/tests/temporary6.out
new file mode 100644
index 00000000..e7af7bba
--- /dev/null
+++ b/keama/tests/temporary6.out
@@ -0,0 +1,33 @@
+{
+ # DHCPv6 temporary (aka IA_TA) range config
+ # subnet declaration
+ /// This configuration declares some subnets but has no interfaces-config
+ /// Reference Kea #245
+ "Dhcp6": {
+ "subnet6": [
+ {
+ "id": 1,
+ "subnet": "2001::/64",
+ "option-data": [
+ # range declaration
+ {
+ "space": "dhcp6",
+ "name": "domain-search",
+ "code": 24,
+// "original-data": "\"example.com\", \"example.org\"",
+ "data": "example.com, example.org"
+ }
+ ],
+ "valid-lifetime": 1800,
+ "pools": [
+// {
+// "pool": "2001::100/64 temporary"
+// }
+// {
+// "pool": "2001::1000/116 temporary"
+// }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/textarray.err b/keama/tests/textarray.err
new file mode 100644
index 00000000..7cecd7a0
--- /dev/null
+++ b/keama/tests/textarray.err
@@ -0,0 +1,7 @@
+# option definition config
+
+# options
+option space foobar;
+
+# array of text are forbidden
+option foobarstring-array code 1 = array of text;
diff --git a/keama/tests/textarray.msg b/keama/tests/textarray.msg
new file mode 100644
index 00000000..f1115cbe
--- /dev/null
+++ b/keama/tests/textarray.msg
@@ -0,0 +1 @@
+textarray.err line 7: arrays of text strings not yet supported.
diff --git a/keama/tests/unknownoption.err b/keama/tests/unknownoption.err
new file mode 100644
index 00000000..ce4aacbb
--- /dev/null
+++ b/keama/tests/unknownoption.err
@@ -0,0 +1,4 @@
+# unknown option config
+
+# unknown option
+option this-option-does-not-exist off;
diff --git a/keama/tests/unknownoption.msg b/keama/tests/unknownoption.msg
new file mode 100644
index 00000000..0fb2f1e9
--- /dev/null
+++ b/keama/tests/unknownoption.msg
@@ -0,0 +1 @@
+unknownoption.err line 4: unknown option dhcp.this-option-does-not-exist
diff --git a/keama/tests/unknownspace.err b/keama/tests/unknownspace.err
new file mode 100644
index 00000000..8165a972
--- /dev/null
+++ b/keama/tests/unknownspace.err
@@ -0,0 +1,4 @@
+# unknown option config
+
+# unknown option
+option this-space-does-not-exist.domain-search "example.com";
diff --git a/keama/tests/unknownspace.msg b/keama/tests/unknownspace.msg
new file mode 100644
index 00000000..f6e378af
--- /dev/null
+++ b/keama/tests/unknownspace.msg
@@ -0,0 +1 @@
+unknownspace.err line 4: no option space named this-space-does-not-exist.
diff --git a/keama/tests/userclass.err b/keama/tests/userclass.err
new file mode 100644
index 00000000..e8a3d27c
--- /dev/null
+++ b/keama/tests/userclass.err
@@ -0,0 +1,6 @@
+# user-class declaration config
+
+# user-class declaration
+user-class "foobar" {
+}
+
diff --git a/keama/tests/userclass.msg b/keama/tests/userclass.msg
new file mode 100644
index 00000000..2208500e
--- /dev/null
+++ b/keama/tests/userclass.msg
@@ -0,0 +1 @@
+userclass.err line 4: obsolete 'user-class' declaration
diff --git a/keama/tests/vendorclass.err b/keama/tests/vendorclass.err
new file mode 100644
index 00000000..81d1b4e3
--- /dev/null
+++ b/keama/tests/vendorclass.err
@@ -0,0 +1,6 @@
+# vendor-class declaration config
+
+# vendor-class declaration
+vendor-class "foobar" {
+}
+
diff --git a/keama/tests/vendorclass.msg b/keama/tests/vendorclass.msg
new file mode 100644
index 00000000..fc45fe66
--- /dev/null
+++ b/keama/tests/vendorclass.msg
@@ -0,0 +1 @@
+vendorclass.err line 4: obsolete 'vendor-class' declaration
diff --git a/keama/tests/vendorspace4.in4 b/keama/tests/vendorspace4.in4
new file mode 100644
index 00000000..98f9eada
--- /dev/null
+++ b/keama/tests/vendorspace4.in4
@@ -0,0 +1,11 @@
+# vendor option space config
+
+option space foo;
+option foo.bar code 1 = text;
+
+# class declaration
+class "foobar" {
+ match if option vendor-class-identifier = "foo";
+ vendor-option-space foo;
+ option foo.bar "foobar";
+}
diff --git a/keama/tests/vendorspace4.out b/keama/tests/vendorspace4.out
new file mode 100644
index 00000000..09feae6f
--- /dev/null
+++ b/keama/tests/vendorspace4.out
@@ -0,0 +1,41 @@
+{
+ # vendor option space config
+ "Dhcp4": {
+ "option-def": [
+ {
+ "space": "foo",
+ "name": "bar",
+ "code": 1,
+ "type": "string"
+ }
+ ],
+ "client-classes": [
+ # class declaration
+ {
+ "name": "foobar",
+ /// from: match if (option dhcp.vendor-class-identifier) = 'foo'
+ "test": "option[60].hex == 'foo'",
+ "option-def": [
+ {
+ "name": "vendor-encapsulated-options",
+ "code": 43,
+ "type": "empty",
+ "encapsulate": "foo"
+ }
+ ],
+ "option-data": [
+ {
+ "name": "vendor-encapsulated-options",
+ "code": 43
+ },
+ {
+ "space": "foo",
+ "name": "bar",
+ "code": 1,
+ "data": "foobar"
+ }
+ ]
+ }
+ ]
+ }
+}
diff --git a/keama/tests/zone4.in4 b/keama/tests/zone4.in4
new file mode 100644
index 00000000..654e6c8e
--- /dev/null
+++ b/keama/tests/zone4.in4
@@ -0,0 +1,24 @@
+# zone executable statement construct
+
+# empty configs are not accepted by Kea
+default-lease-time 1800;
+
+# a zone
+zone example.com {
+ primary 10.5.5.1, 10.5.5.2;
+ secondary 10.10.10.1;
+ primary6 2001::1, 2001::2;
+ secondary6 2002::1;
+ key "mykey";
+}
+
+# a key;
+key "mykey" {
+ algorithm hmac-md5;
+ secret "somekeydata";
+}
+
+# another key (with bind 8 semi-colon)
+key example.com {
+ algorithm aes-gmac.dreams;
+};
diff --git a/keama/tests/zone4.out b/keama/tests/zone4.out
new file mode 100644
index 00000000..7565db4c
--- /dev/null
+++ b/keama/tests/zone4.out
@@ -0,0 +1,47 @@
+{
+ # zone executable statement construct
+ # empty configs are not accepted by Kea
+ "Dhcp4": {
+ "valid-lifetime": 1800
+// # a zone
+// "statement": {
+// "zone": {
+// "name": "example.com.",
+// "primary": [
+// "10.5.5.1",
+// "10.5.5.2"
+// ],
+// "secondary": [
+// "10.10.10.1"
+// ],
+// "primary6": [
+// "2001::1",
+// "2001::2"
+// ],
+// "secondary6": [
+// "2002::1"
+// ],
+// "key": "mykey"
+// }
+// }
+// # a key;
+// "statement": {
+// "tsig-keys": [
+// {
+// "name": "mykey",
+// "algorithm": "hmac-md5.SIG-ALG.REG.INT.",
+// "secret": "somekeydata"
+// }
+// ]
+// }
+// # another key (with bind 8 semi-colon)
+// "statement": {
+// "tsig-keys": [
+// {
+// "name": "example.com",
+// "algorithm": "aes-gmac.dreams."
+// }
+// ]
+// }
+ }
+}