{"record":{"id":"10ea5bbe552724ac","repo":"TechnitiumSoftware/DnsServer","slug":"client-hardware-address-cannot-exceed-16-bytes","errorCode":null,"errorMessage":"Client hardware address cannot exceed 16 bytes.","messagePattern":"Client hardware address cannot exceed 16 bytes\\.","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"DnsServerCore/Dhcp/DhcpMessage.cs","lineNumber":113,"sourceCode":"\n        public DhcpMessage(DhcpMessageOpCode op, DhcpMessageHardwareAddressType hardwareAddressType, byte[] xid, byte[] secs, DhcpMessageFlags flags, IPAddress ciaddr, IPAddress yiaddr, IPAddress siaddr, IPAddress giaddr, byte[] clientHardwareAddress, string sname, string file, IReadOnlyCollection<DhcpOption> options)\n        {\n            if (ciaddr.AddressFamily != AddressFamily.InterNetwork)\n                throw new ArgumentException(\"Address family not supported.\", nameof(ciaddr));\n\n            if (yiaddr.AddressFamily != AddressFamily.InterNetwork)\n                throw new ArgumentException(\"Address family not supported.\", nameof(yiaddr));\n\n            if (siaddr.AddressFamily != AddressFamily.InterNetwork)\n                throw new ArgumentException(\"Address family not supported.\", nameof(siaddr));\n\n            if (giaddr.AddressFamily != AddressFamily.InterNetwork)\n                throw new ArgumentException(\"Address family not supported.\", nameof(giaddr));\n\n            ArgumentNullException.ThrowIfNull(clientHardwareAddress);\n\n            if (clientHardwareAddress.Length > 16)\n                throw new ArgumentException(\"Client hardware address cannot exceed 16 bytes.\", nameof(clientHardwareAddress));\n\n            if (xid.Length != 4)\n                throw new ArgumentException(\"Transaction ID must be 4 bytes.\", nameof(xid));\n\n            if (secs.Length != 2)\n                throw new ArgumentException(\"Seconds elapsed must be 2 bytes.\", nameof(secs));\n\n            _op = op;\n            _htype = hardwareAddressType;\n            _hlen = Convert.ToByte(clientHardwareAddress.Length);\n            _hops = 0;\n\n            _xid = xid;\n\n            _secs = secs;\n            _flags = flags;\n\n            _ciaddr = ciaddr;","sourceCodeStart":95,"sourceCodeEnd":131,"githubUrl":"https://github.com/TechnitiumSoftware/DnsServer/blob/d0484b6c1e7439cdc53d67d81e9c876cda2ad756/DnsServerCore/Dhcp/DhcpMessage.cs#L95-L131","documentation":"Constructor argument guard in DhcpMessage: clientHardwareAddress must not exceed 16 bytes. RFC 2131 fixes the 'chaddr' field at exactly 16 bytes; the constructor copies the supplied hardware address into a 16-byte buffer via Buffer.BlockCopy, so anything longer would overflow/truncate. The hlen byte also stores the length.","triggerScenarios":"Calling the DhcpMessage constructor with a clientHardwareAddress byte array longer than 16 bytes.","commonSituations":"Passing a non-Ethernet hardware identifier (e.g. a long client-id, a GUID, a concatenated identifier) where a MAC address is expected; IPv6 interface tokens; a DHCPv6 client identifier reused for DHCPv4.","solutions":["Pass only the Layer-2 hardware address (typically a 6-byte Ethernet MAC) as clientHardwareAddress.","Move long client identifiers into a DHCP Client Identifier option instead of chaddr.","Truncate/normalize the identifier to <= 16 bytes if it legitimately encodes a longer link-layer address.","Validate clientHardwareAddress.Length before constructing."],"exampleFix":"// before\nbyte[] chaddr = clientId; // 20-byte client identifier\nvar msg = new DhcpMessage(op, htype, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr, chaddr, sname, file, opts); // throws [215]\n\n// after: MAC in chaddr, client-id in an option\nbyte[] chaddr = nic.GetPhysicalAddress().GetAddressBytes(); // 6 bytes\nvar opts2 = new List<DhcpOption>(opts) { new ClientIdentifierOption(chaddr) };\nvar msg = new DhcpMessage(op, htype, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr, chaddr, sname, file, opts2);","handlingStrategy":"validation","validationCode":"const int MAX_CHADDR = 16;\nif (clientHardwareAddress is null) throw new ArgumentNullException(nameof(clientHardwareAddress));\nif (clientHardwareAddress.Length > MAX_CHADDR)\n    throw new ArgumentException($\"Client hardware address must be <= {MAX_CHADDR} bytes.\", nameof(clientHardwareAddress));\n\nvar msg = new DhcpMessage(op, htype, xid, secs, flags, ciaddr, yiaddr, siaddr, giaddr, clientHardwareAddress, sname, file, opts);","typeGuard":"static bool IsValidChaddr(byte[] chaddr) =>\n    chaddr is not null && chaddr.Length <= 16;","tryCatchPattern":null,"preventionTips":["Pass the Layer-2 MAC address (typically 6 bytes) as chaddr.","Move long client identifiers into a DHCP Client Identifier option, not chaddr.","Validate length before constructing DhcpMessage."],"tags":["dhcp","validation","constructor","rfc2131","mac-address"],"backgroundTag":null,"analyzedSha":"d0484b6c1e7439cdc53d67d81e9c876cda2ad756","analyzedAt":"2026-08-13T22:57:35.508Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}