-
Notifications
You must be signed in to change notification settings - Fork 391
Add parsing of well known IPv6 extension headers #287
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
Add parsing of well known IPv6 extension headers #287
Conversation
Add classes for IPv6 extension headers defined in the IPv6 protocol specification (RFC 2460) as well as functions for creating them from the IPv6 class' ext_header type. The currently known extension headers are Hop-By-Hop Option, Destination Routing, Routing and Fragment.
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.
Thanks for this PR! I'll look into the protocol formatting specifics later but overall it looks great.
src/ipv6.cpp
Outdated
@@ -169,6 +212,33 @@ uint32_t IPv6::get_padding_size(const ext_header& header) { | |||
return padding == 0 ? 0 : (8 - padding); | |||
} | |||
|
|||
std::vector<IPv6::header_option_type> IPv6::parse_header_options(const uint8_t* data, size_t size) | |||
{ |
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.
Can you move this brace up to the end of the previous line?
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.
Sure. Tried to keep the same coding style as the existing code, but I'm not surprised if I've missed a few places.
src/ipv6.cpp
Outdated
@@ -169,6 +212,33 @@ uint32_t IPv6::get_padding_size(const ext_header& header) { | |||
return padding == 0 ? 0 : (8 - padding); | |||
} | |||
|
|||
std::vector<IPv6::header_option_type> IPv6::parse_header_options(const uint8_t* data, size_t size) |
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.
I'm trying to keep cpp files away from using "namespace specifiers" everywhere and instead just have using std::something
at the top. In fact, std::vector
is already pulled like this so you can just remove std::
here (there's also a couple other occurrences of this in the body of this method).
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.
Will do.
src/ipv6.cpp
Outdated
} | ||
if (option != PAD_N) { | ||
std::vector<uint8_t> value(stream.pointer(), stream.pointer() + size); | ||
options.push_back(std::make_pair(option, value)); |
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.
So this sucks because I'm trying to keep the codebase both C++03 and C++11 compliant. If this was C++11 you would do:
options.push_back(make_pair(option, move(value)));
So you avoid creating an unnecessary copy of the vector. So in this case you can either have some ugly ifdef TINS_IS_CXX11
and use move, otherwise do what this is moving or you can just move this into a single expression:
options.push_back(make_pair(option, vector<uint8_t>(stream.pointer(), stream.pointer() + size)));
Possibly having to split that in multiple lines if it's too long.
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.
I thought a bit about that actually and was pretty sure the compiler could probably optimize the copy away, but I never tested that.
Anyway since this library has to support C++03, I much prefer your second option over ugly #ifdefs, so I'll go with that.
Well spotted.
src/ipv6.cpp
Outdated
routing_header header; | ||
header.routing_type = stream.read<uint8_t>(); | ||
header.segments_left = stream.read<uint8_t>(); | ||
header.data = std::vector<uint8_t>(stream.pointer(), stream.pointer() + stream.size()); |
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.
You can just do
header.data.assign(stream.pointer(), stream.pointer() + stream.size());
``
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.
Of course. Thanks for pointing this out.
Pull in stuff from the std namespace with "using" instead of qualifying with std::. Keep starting braces on the same line. Avoid potential copy when appending to vector.
Concerning the protocol format specifics, I haven't really been able to find any pcap files or other ways to tests this with "real life data" so this has mostly but written from what is described in RFC 2460. Since your library makes it incredibly easy to write pcap files, I have tried writing my test data to pcap files and made sure that Wireshark and my code agreed on how the packets should be parsed, but that's the only kind of testing I could really think of. |
Thanks, looks good! |
Add classes for IPv6 extension headers defined in the IPv6 protocol
specification (RFC 2460) as well as functions for creating them from
the IPv6 class' ext_header type.
The currently known extension headers are Hop-By-Hop Option,
Destination Routing, Routing and Fragment.