# net.device-validate Checks one entry of a network inventory file (the list of devices a monitor probes) and reports every problem with it at once, instead of the first one. An entry looks like this: ```json { "name": "core-switch", "host": "10.0.0.2", "ports": [22, 443], "mac": "AA-BB-CC-DD-EE-FF", "subnet": "10.0.0.0/24" } ``` `name`, `host` and `ports` are required; `mac` and `subnet` are optional (null is the same as leaving them out). The function never throws: a bad entry is a result with `valid: false` and a list of `errors`, so a monitor can report it and carry on with the rest of the file. ## What each field must be | field | rule | built on | |-------|------|----------| | `name` | text, not blank; ASCII whitespace around it is trimmed | | | `host` | an IPv4 address, an IPv6 address or an RFC 1123 host name, tried in that order | `net.ipv4`, `net.ipv6`, `net.hostname-validate` | | `ports` | a non-empty list of whole numbers 1-65535, each once | `net.port` | | `mac` | an EUI-48 MAC in any of the forms `net.mac-address` accepts | `net.mac-address` | | `subnet` | an IPv4 or IPv6 CIDR block | `net.cidr` | Anything else in the entry is reported as `unknown field "x"`, which catches typos such as `"port"` for `"ports"`. Unknown fields are listed in sorted order after the field errors, because JavaScript orders integer-like keys first and "file order" would differ between languages. ## The normal forms returned - `host`: an IPv4 address as given (it can only be valid in one spelling), IPv6 in RFC 5952 canonical form, a host name lower-cased without its trailing dot. `hostKind` says which of `ipv4`, `ipv6` or `hostname` it is. - `ports`: the valid ports in order, a repeated one only once. `22.0` is port 22, since a JSON reader may store it as a float. - `mac`: lower-case, colon-separated. - `subnet`: host bits cleared (`10.0.0.77/24` is `10.0.0.0/24`), the address of an IPv6 block in RFC 5952 form. Fields that fail are null (or left out of `ports`) in the result, while the rest are still normalised, so a report can name the device whose MAC is bad. ## Edge cases - `192.168.1.256` and `010.0.0.1` are not IPv4 addresses (out of range, and a leading zero that some parsers read as octal), and they are not host names either: a top-level label may not be all digits (RFC 3696 section 2). A naive check lets them through as names. - A trailing newline is not trimmed from `host`; it makes the entry invalid. - Subnet membership is not checked here: a host name has no address until it is resolved, which is I/O. Check it afterwards with `net.cidr`'s `cidrContains` on the resolved address.