Skip to content

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

Merged
merged 2 commits into from
Mar 29, 2018

Conversation

laudrup
Copy link
Contributor

@laudrup laudrup commented Mar 27, 2018

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.

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.
Copy link
Owner

@mfontanini mfontanini left a 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)
{
Copy link
Owner

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?

Copy link
Contributor Author

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)
Copy link
Owner

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).

Copy link
Contributor Author

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));
Copy link
Owner

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.

Copy link
Contributor Author

@laudrup laudrup Mar 28, 2018

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());
Copy link
Owner

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());
``

Copy link
Contributor Author

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.
@laudrup
Copy link
Contributor Author

laudrup commented Mar 28, 2018

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.

@mfontanini mfontanini changed the base branch from master to develop March 29, 2018 03:45
@mfontanini
Copy link
Owner

Thanks, looks good!

@mfontanini mfontanini merged commit fa79582 into mfontanini:develop Mar 29, 2018
@laudrup laudrup deleted the ipv6-extension-header-parsing branch March 29, 2018 12:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants