-
Notifications
You must be signed in to change notification settings - Fork 172
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Cater for bad client implementation of vendor class option length #395
Cater for bad client implementation of vendor class option length #395
Conversation
…ng little-endian rather than big-endian (seen in the wild). Signed-off-by: David Barr <[email protected]>
e1b5314
to
c63ab73
Compare
Is this only happening with the vendor class option? I am not a great fan of introducing quirks for specific vendors but will wait for other opinions. Right now if the parsing of 1 option fails in DHCPv6, we fail to parse the whole packet. This is not the case with DHCPv4 where we do lazy parsing. We should uniform this #22. |
Yes it is.
Neither am I!
This would be my preferred option too. I'm not actually doing anything with the vendor class at present, but as you say it causes the whole packet to fail to parse. I also have another parsing failure where the vendor class has an EnterpriseNumber, but no vendor-class-data. The only other solution I could think of would be to allow the ability to send in a custom replacement for ParseOption, so you could inject your own logic in the option parser if needed, but it would probably be more rework than it's worth. I'm happy to close this and focus some effort on #22 if you'd like? |
@@ -47,6 +47,10 @@ func ParseOptVendorClass(data []byte) (*OptVendorClass, error) { | |||
opt.EnterpriseNumber = buf.Read32() | |||
for buf.Has(2) { | |||
len := buf.Read16() | |||
// Assume little-endian if big-endian would have resulted in an error | |||
if len > 0 && !buf.Has(int(len)) { | |||
len = len>>8 | (len & 0xff << 8) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is... just the vendor option in little endian...? All other length fields are the correct endianness, for the other options?
This works if all other lengths happen to be correct, i.e. the correct length buffer for this option was passed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes the rest of the packet is fine, it was just the vendor class option with the little-endian length.
The vendor class option I was seeing was:
0 16 0 18 0 0 13 233 12 0 100 115 108 102 111 114 117 109 46 111 114 103
where:
0 16(OptionVendorClass)
0 18(option length)
0 0 13 233(enterprise-number)
12 0(vendor-class-len)
100 115 108 102 111 114 117 109 46 111 114 103 (opaque-data)
Not sure if subsequent items would have followed the same byte order for the vendor-class-len as only one item was present.
When I started all this, I was hoping to turn dhcpv6 into lazy parsing too. (Also, sorry, I see you already answered these questions.) Maybe it's time to do that. I might give it a try this weekend to avoid perf. |
That'd be great! I have also "fixed" this in FromBytesWithParser by changing: opt, err := parser(code, optData)
if err != nil {
return err
} to opt, _ := parser(code, optData) and in ParseOption(), one could change: if err != nil {
return nil, err
}
return opt, err to: return opt, err to keep the Option (even though part of it might be in a "garbled" state depending on how parsing went). In my case above it results in You do lose access any to underlying errors, but dhcpv4 suffers from the same issue. Interestingly enough, the changes here don't result in any failed tests. |
Alternatively, we could create a special OptionParseFailure option (or some other name, like OptionGenericParseFailure) which contains the original option and the error and a .String() could call the Option's .String() and also display the error. |
Shall we close this PR? |
Hi team, long time no see.
I needed the attached pull request to cater for a bad client implementation of the vendor class option length using little-endian rather than big-endian that I am seeing in the wild on certain D-Link routers.
Cheers!