summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* libfdt: Add fdt_check_full() functionsafetyDavid Gibson2018-04-117-1/+141
| | | | | | | | | | This new function implements a complete and thorough check of an fdt blob's structure. Given a buffer containing an fdt, it should return 0 only if the fdt within is structurally sound in all regards. It doesn't check anything about the blob's contents (i.e. the actual values of the nodes and properties), of course. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Use valgrind client requests for better checkingDavid Gibson2018-04-114-1/+56
| | | | | | | | | | | | | | | libfdt is never supposed to access memory outside the the blob, or outside the sub-blocks within it, even if the blob is badly corrupted. We can leverage valgrind's client requests to do better testing of this. This adds a vg_prepare_blob() function which marks just the valid parts of an fdt blob as properly initialized, explicitly marking the rest as uninitialized. This means valgrind should catch any bad accesses. We add a call to vg_prepare_blob() to load_blob() so that lots of the existing testcases will benefit from the extra checking. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Better handling of valgrind errors saving blobsDavid Gibson2018-04-114-34/+13
| | | | | | | | | | | | | | Currently we have 3 valgrind suppression files in the tests, all of which are to handle memcheck errors that originate from saving entire buffers containing blobs where the gaps between sub-blocks might not be initialized. We can more simply suppress those errors by having the save_blob() helper use valgrind's client interface to mark the data as initialized before we write it out. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Simon Glass <sjg@chromium.org>
* tests: Remove unused #defineDavid Gibson2018-04-111-2/+0
| | | | | | | This was leftover from an earlier implementation of load_blob(). Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Simon Glass <sjg@chromium.org>
* Use size_t for blob lengths in utilfdt_read*David Gibson2018-04-114-7/+7
| | | | | | | | It's more appropriate than off_t since it is, after all, a size not an offset. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Simon Glass <sjg@chromium.org>
* libfdt: Add fdt_header_size()David Gibson2018-04-113-10/+28
| | | | | | | | | We have a couple of places within libfdt and its tests where we need to find the size of the header, based on the version. Add a helper function for it. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Simon Glass <sjg@chromium.org>
* Consolidate utilfdt_read_len() variantsDavid Gibson2018-04-117-38/+15
| | | | | | | | | | | | There are no less than _four_ variants on utilfdt_read() which is a bit excessive. The _len() variants are particularly pointless, since we can achieve the same thing with very little extra verbosity by using the usual convention of ignoring return parameters if they're NULL. So, get rid of them (we keep the shorter names without _len, but add now-optional len parameters). Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Simon Glass <sjg@chromium.org>
* libfdt: Safer access to memory reservationsDavid Gibson2018-04-117-7/+114
| | | | | | | | | | | | fdt_num_mem_rsv() and fdt_get_mem_rsv() currently don't sanity check their parameters, or the memory reserve section offset in the header. That means that on a corrupted blob they could access outside of the range of memory that they should. This improves their safety checking, meaning they shouldn't access outside the blob's bounds, even if its contents are badly corrupted. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* libfdt: Propagate name errors in fdt_getprop_by_offset()David Gibson2018-04-111-2/+12
| | | | | | | | | fdt_getprop_by_offset() doesn't check for errors from fdt_string() - after all, until very recently it couldn't fail. Now it can, so we need to propagate errors up to the caller. Signed-off-by: David Gibson <david@gibson.dropbear.id.au> Reviewed-by: Simon Glass <sjg@chromium.org>
* libfdt: Safer access to strings sectionDavid Gibson2018-04-1110-9/+193
| | | | | | | | | | | | | | | | | | | | | fdt_string() is used to retrieve strings from a DT blob's strings section. It's rarely used directly, but is widely used internally. However, it doesn't do any bounds checking, which means in the case of a corrupted blob it could access bad memory, which libfdt is supposed to avoid. This write a safe alternative to fdt_string, fdt_get_string(). It checks both that the given offset is within the string section and that the string it points to is properly \0 terminated within the section. It also returns the string's length as a convenience (since it needs to determine to do the checks anyway). fdt_string() is rewritten in terms of fdt_get_string() for compatibility. Most of the diff here is actually testing infrastructure. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* libfdt: Make fdt_check_header() more thoroughDavid Gibson2018-04-117-4/+192
| | | | | | | | | | | | | | | | | | | | Currently fdt_check_header() performs only some rudimentary checks, which is not really what the name suggests. This strengthens fdt_check_header() to check as much about the blob as is possible from the header alone: as well as checking the magic number and version, it checks that the total size is sane, and that all the sub-blocks within the blob lie within the total size. * This broadens the meaning of FDT_ERR_TRUNCATED to cover all sorts of improperly terminated blocks as well as just a structure block without FDT_END. * This makes fdt_check_header() only succeed on "complete" blobs, not in-progress sequential write blobs. The only reason this didn't fail before was that this function used to be called by many RO functions which are supposed to also work on incomplete SW blobs. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* libfdt: Improve sequential write state checkingDavid Gibson2018-04-115-15/+218
| | | | | | | | | | | | | | | When creating a tree with the sequential write functions, certain things have to be done in a certain order. You must create the memory reserve map and only then can you create the actual tree structure. The -FDT_ERR_BADSTATE return code is for if you try to do things out of order. However, we weren't checking that very thoroughly, so it was possible to generate a corrupted blob if, for example, you started calling fdt_begin_node() etc. before calling fdt_finish_reservemap(). This makes the state checking more thorough disallow that. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* libfdt: Clean up header checking functionsDavid Gibson2018-04-046-39/+45
| | | | | | | | | | | | | | | | | Many of the libfdt entry points call some sort of sanity check function before doing anything else. These need to do slightly different things for the various classes of functions. The read-only version is shared with the exported fdt_check_header(), which limits us a bit in how we can improve it. For that reason split the two functions apart (though the exported one just calls the ro one for now). We also rename the functions for more consistency - they're all named fdt_XX_probe_() where the XX indicates which class of functions they're for. "probe" is a better "term" than the previous check, since they really only do minimal validation. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: Print duplicate node name instead of parent nameGeert Uytterhoeven2018-03-281-1/+1
| | | | | | | | | | When refactoring node path printing, the code checking for duplicate node names was accidentally changed to print the name of the parent node, instead of the name of the duplicated child node. Fixes: 88960e3989073207 ("checks: centralize printing of node path in check_msg") Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* .travis.yml: Run valgrind checks via TravisDavid Gibson2018-03-091-2/+6
| | | | | | To improve our coverage, run the testsuite under Valgrind via Travis. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Update valgrind suppressions for sw_tree1David Gibson2018-03-091-1/+1
| | | | | | | | | | | | | | | | | | This test builds a tree in a previously uninitialized buffer, then writes the whole buffer out to a file to be used by other tests. Because part of the buffer may be uninitialized this causes a valgrind error. Pre-initializing the buffer would remove the error, however it would make valgrind not notice any accesses to the uninitialized portion *before* the write out, and those would be genuine errors. So, instead we use a valgrind suppressions file - however it has a couple of problems. First it unnecessarily lists the same call path twice. Second, the call path is only right for some C library versions. Change the second copy to cover possible path that occurs with a different glibc version. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Remove valgrind error from tests/get_pathDavid Gibson2018-03-091-1/+2
| | | | | | | | In the case where fdt_get_path() returns an error, a debug print will attempt to display a poisoned buffer, running over the end and accessing uninitialized memory. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add graph binding checksRob Herring2018-03-073-0/+175
| | | | | | | | | | | | | | Add checks for DT graph bindings. These checks check node names, unit-addresses and link connections on ports, port, and endpoint nodes. The graph nodes are matched by finding nodes named 'endpoint' or with a 'remote-endpoint' property. We can't match on 'ports' or 'port' nodes because those names are used for non-graph nodes. While the graph nodes aren't really buses, using the bus pointer to tag matched nodes is convenient. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add a check for duplicate unit-addresses of child nodesRob Herring2018-03-073-0/+46
| | | | | | | | | | | | | | | | | | | | Child nodes with the same unit-address (and different node names) are either an error or just bad DT design. Typical errors are the unit-address is just wrong (i.e. doesn't match reg value) or multiple children using the same overlapping area. Overlapping regions are considered an error in new bindings, but do exist in some existing trees. This check should flag most but not all of those errors. Finding all cases would require doing address translations and creating a full map of address spaces. Mixing more than one address/number space at a level is bad design. It only works if both spaces can use the same #address-cells and #size-cells sizes. It also complicates parsing have a mixture of types of child nodes. The best practice in this case is adding child container nodes for each address/number space or using additional address bits/cells to encode different address spaces. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Correct overlay syntactic sugar for generating target-path fragmentsDavid Gibson2018-03-064-14/+80
| | | | | | | | | | | | | | | | | | | | | | | | | | We've recently added "syntactic sugar" support to generate runtime dtb overlays using similar syntax to the compile time overlays we've had for a while. This worked with the &label { ... } syntax, adjusting an existing labelled node, but would fail with the &{/path} { ... } syntax attempting to adjust an existing node referenced by its path. The previous code would always try to use the "target" property in the output overlay, which needs to be fixed up, and __fixups__ can only encode symbols, not paths, so the result could never work properly. This adds support for the &{/path} syntax for overlays, translating it into the "target-path" encoding in the output. It also changes existing behaviour a little because we now unconditionally one fragment for each overlay section in the source. Previously we would only create a fragment if we couldn't locally resolve the node referenced. We need this for path references, because the path is supposed to be referencing something in the (not yet known) base tree, rather than the overlay tree we are working with now. In particular one useful case for path based overlays is using &{/} - but the constructed overlay tree will always have a root node, meaning that without the change that would attempt to resolve the fragment locally, which is not what we want. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Suppress warnings on overlay fragmentsDavid Gibson2018-03-061-0/+5
| | | | | | | | | | Overlay fragments are traditionally named "fragment@NNN" but don't have have a 'reg' property, amongst other differences from normal nodes. Really we should treat overlay fragments fundamentally differently, but for the moment, suppress the common warnings about the fragment names with this simple hack. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Improve tests for dtc overlay generationDavid Gibson2018-03-064-81/+146
| | | | | | | | | | | | | | So far, the tests for generating runtime overlays with dtc weren't checking the syntactic sugar. This adds such a test. Furthermore the existing tests were only minimally testing dtc's output for the overlay. This adds a test comparing the dtc output with the more or less manually constructed overlays we already have for testing libfdt's overlay application code. This does require some minor changes to that manually constructed overlay which don't change the sematics but re-order / rename things to match the way dtc does it. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: centralize printing of property names in failure messagesRob Herring2018-02-101-68/+80
| | | | | | | | | | | | | | Some failure messages apply to a specific property. Add a FAIL_PROP() macro for failure messages which are specific to a property. With that, failure messages can print the property name in a standard way. Once source line numbers are supported, then the file and line number of the property can be used instead of the node file and line number. Convert the existing messages related to properties to use the FAIL_PROP macro and reword the messages as necessary. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: centralize printing of node path in check_msgRob Herring2018-02-091-128/+104
| | | | | | | | | | | Most error/warning messages print the node path as part of their error message. Move printing of the node path into check_msg() so the formatting can be standardized to the form: <output file>: (ERROR|warning) (<check name>): <full node name>: <check message> Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Add limited read-only support for older (V2 and V3) device tree to libfdt.Nathan Whitehorn2018-01-274-19/+93
| | | | | | | | | | This can be useful in particular in the kernel when booting on systems with FDT-emitting firmware that is out of date. Releases of kexec-tools on ppc64 prior to the end of 2014 are notable examples of such. Signed-off-by: Nathan Whitehorn <nwhitehorn@freebsd.org> [dwg: Some whitespace cleanups] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* srcpos: drop special handling of tabJulia Lawall2018-01-231-5/+0
| | | | | | | | Align column number with those reported by gcc. Thus, do not make a tab count as 8 spaces. Signed-off-by: Julia Lawall <Julia.Lawall@lip6.fr> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* libfdt: overlay: Add missing licenseMaxime Ripard2018-01-101-0/+51
| | | | | | | | The overlay support has been introduced, but the copyright and license header was missing. Make sure that this is no longer the case. Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Avoid installing pylibfdt when dependencies are missingSimon Glass2018-01-081-8/+16
| | | | | | | | | | | | | | | At present we have a build check that python-dev and swig are available. If they are not, we print a message and skip building pylibfdt. However this check is not currently present with 'make install'. The install is attempted, and fails. See crbug.com/789189 Split the check out into a separate script and use it twice, once for the build and once for the install. This corrects the error. Reported-by: Mike Frysinger <vapier@chromium.org> Signed-off-by: Simon Glass <sjg@chromium.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile: Split INSTALL out into INSTALL_{PROGRAM,LIB,DATA,SCRIPT}kevans@FreeBSD.org2018-01-041-4/+9
| | | | | | | | | | | For adoption into systems that may have additional arguments to be passed into install(1) upon install, split out INSTALL into the different types of files to be installed and use them appropriately. This allows, for instance, passing -s to strip binaries and libs while not botching directory installs or data/script installations. Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Makefile.tests: Add LIBDL make(1) variable for portability sakekevans@FreeBSD.org2018-01-041-1/+4
| | | | | | | | | | Some platforms (many, if not all, of the *BSD projects) do not provide a libdl, and instead provide the same functionality in libc. Instead of forcing these platforms to patch out the link against libdl, add a LIBDL make(1) variable to allow the -ldl argument to be excluded easily via make(1) arguments. Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Attempt to auto-detect stat(1) being used if not given proper invocationkevans@FreeBSD.org2018-01-041-1/+8
| | | | | | | | | | | | | GNU stat(1) uses '-c "%s"' as the proper invocation to print filesize of the file in question, while BSD stat(1) uses '-f "%Uz"'. Do some trivial autodetection to check if we're using GNU stat(1) and assume we're using BSD stat(1) if we don't detect otherwise. This should allow the test suite to run properly out-of-the-box on *BSDs and MacOS in addition to the current Linux support. Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* dtc: Bump version to v1.4.6v1.4.6David Gibson2018-01-031-1/+1
| | | | | | | We've accumulated a number of bugfixes since v1.4.5, so prepare for another release. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* fdtoverlay: Switch from using alloca to mallockevans@FreeBSD.org2018-01-031-2/+2
| | | | | | | | | | | alloca entails a complicated header situation when using other platforms, where some split it out in alloca.h while others include it as a standard part of stdlib.h. The cons don't seem to outweigh the pros, so switch it to malloc. Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Improve compatibility with other platformskevans@FreeBSD.org2018-01-031-4/+9
| | | | | | | | | stat -c %s's equivalent on FreeBSD is stat -f %Uz; these differ enough, allow STATSZ in the environment to specify local replacement for a stat that outputs size in bytes of an argument. Signed-off-by: Kyle Evans <kevans@FreeBSD.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add chosen node checksRob Herring2017-12-153-0/+64
| | | | | | | | Add some checks for /chosen node. These check that chosen is located at the root level and that bootargs and stdout-path properties are strings. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add aliases node checksRob Herring2017-12-131-0/+24
| | | | | | | | Add checks for aliases node that all properties follow alias naming convention and the values are a valid path. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: check for #{size,address}-cells without child nodesRob Herring2017-12-131-0/+26
| | | | | | | | | | | Add a check for unnecessary "#{size,address}-cells" when there's neither a 'ranges' property nor child nodes with a 'reg' property. An exception may be an overlay that adds nodes, but this case would need "#{size,address}-cells" in the overlay to properly compile already. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add string list check for *-names propertiesRob Herring2017-12-133-2/+19
| | | | | | | | Add a string list check for common properties ending in "-names" such as reg-names or interrupt-names. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add string list checkRob Herring2017-12-133-1/+40
| | | | | | | | Add a check for string list properties with compatible being the first check. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: add a string check for 'label' propertyRob Herring2017-12-133-1/+4
| | | | | | | | Add a string property check for 'label' property. 'label' is a human readable string typically used to identify connectors or ports on devices. Signed-off-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* checks: fix sound-dai phandle with arg property checkPeter Rosin2017-12-051-2/+2
| | | | | | | | | The property is named "sound-dai", not "sound-dais". Fixes: b3bbac02d5e3 ("checks: add phandle with arg property checks") Signed-off-by: Peter Rosin <peda@axentia.se> Reviewed-by: Rob Herring <robh@kernel.org> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Fix ambiguous grammar for devicetree ruleGrant Likely2017-11-213-8/+14
| | | | | | | | | | | | | | | | | | | | Commit 737b2df3, "overlay: Add syntactic sugar version of overlays" introduced an empty rule for "devicetree" that created ambiguities in the grammar and causes the following warning: BISON dtc-parser.tab.c dtc-parser.y: warning: 3 shift/reduce conflicts [-Wconflicts-sr] Fix the grammar by explicitly testing for the condition the new overlay grammar wants to use. This means duplicating a very small amount of grammar processing code, but the alternative seems to be a more invasive reorganization of the devicetree rule. Better to fix it this way now and save the reorg for a separate patch. Signed-off-by: Grant Likely <grant.likely@arm.com> Cc: Pantelis Antoniou <pantelis.antoniou@konsulko.com> Cc: David Gibson <david@gibson.dropbear.id.au> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Add some basic tests for the pci_bridge checksDavid Gibson2017-11-114-0/+61
| | | | | | | This adds some simple tests for the checks of correctly formatted PCI bridge nodes. Doesn't test all that much, but it's a start. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Fix widespread incorrect use of strneq(), replace with new strprefixeq()David Gibson2017-11-113-5/+5
| | | | | | | | | | | | | | Every remaining usage of strneq() is, in fact, incorrect. They're trying to check that the first n characters of one string exactly match another string. But, they fall into the classic trap of strncmp() on which strneq() is based. If n is less than the length of the second string, they only check that the first string matches the start of the second, not the whole of it. To fix this, remove strneq() and replace it with a strprefixeq() function which does what we want here. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Add strstarts() helper functionDavid Gibson2017-11-112-1/+2
| | | | | | | | | nodename_from_path() in flattree.c uses strneq() to test that one string starts with another. This is, in fact, the only correct usage of strneq() in the entire tree. To make things harder to confuse, add a strstarts() function for this purpose. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* tests: Check non-matching cases for fdt_node_check_compatible()David Gibson2017-10-301-0/+19
| | | | | | | | | The current tests for fdt_node_check_compatible() test that it returns true on several matching cases, but don't test that it actually returns false on some non-matching cases, which isn't great coverage. Add some basic tests to address that. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* livetree: avoid assertion of orphan phandles with overlaysTero Kristo2017-10-272-2/+6
| | | | | | | | | | | | | | Right now, check_interrupts_property fails with overlays, as the phandle for the interrupt-parent can be orphan. Avoid this by allowing the orphan node to pass the assert check. The process_checks() call is also moved later during init sequence, so that we can use the global variable generate_fixups to check if we are compiling an overlay. Signed-off-by: Tero Kristo <t-kristo@ti.com> [dwg: Shortcut handling of invalid phandles] Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* implement strnlen for systems that need itJohn Arbuckle2017-10-271-0/+27
| | | | | | | | Prior the Mac OS 10.7, the function strnlen() was not available. This patch implements strnlen() on Mac OS X versions that are below 10.7. Signed-off-by: John Arbuckle <programmingkidx@gmail.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* libfdt: Remove leading underscores from identifiersDavid Gibson2017-10-269-120/+120
| | | | | | | | | | | | | | In a lot of places libfdt uses a leading _ character to mark an identifier as "internal" (not part of the published libfdt API). This is a bad idea, because identifiers with a leading _ are generally reserved by the C library or system. It's particularly dangerous for libfdt, because it's designed to be able to be integrated into lots of different environments. In some cases the leading _ has no purpose, so we simply drop it. In most cases we move it to the end, as our new convention for marking internal identifiers. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
* Remove leading underscores from identifiersDavid Gibson2017-10-2610-43/+41
| | | | | | | | | | | | | | In a number of places, dtc and associated tools and test code use leading _ characters on identifiers to flag them as "internal", an idiom taken from the Linux kernel. This is a bad idea in a userspace program, because identifiers with a leading _ are reserved for the C library / system. In some cases, the extra _ served no real purpose, so simply drop it. In others move to the end of the identifier, which is a convention we're free to use for our own purposes. Signed-off-by: David Gibson <david@gibson.dropbear.id.au>