Skip to content
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

Interface down message and de-duplicated loopback packets #54

Conversation

awelzel
Copy link
Contributor

@awelzel awelzel commented Mar 29, 2023

Fixes #51 and #53 .

awelzel added 3 commits March 29, 2023 15:13
zeek/zeek-dev contains AF_Packet builtin. Use zeek/zeek:5.0.7 for now.

Going forward we may want to remove the Dockerfile again, or add something
complex that builds Zeek from scratch, or accept that it'll be hard to
test this as an external plugin and developing in-tree is easier.
...not sure why they are marked inline.
Technically, socket() can return 0, so shouldn't use it as an
indication of a non existent / closed socket.

I'm not 100% sure about the Close() contract here: If something
goes haywire with a packet source Zeek calls FatalError without
calling Close() nor properly destructing the PktSrc. Oh yikes.
When using af_packet with an interface that was not up, the following
non-informative error was reported:

    $ /opt/zeek-5.2/bin/zeek -i af_packet::replay
    fatal error: problem with interface af_packet::replay (Invalid argument)

With this change, the error now includes information about the
interface being down:

    $ ZEEK_PLUGIN_PATH=$(pwd)/build zeek -Ci af_packet::replay
    fatal error: problem with interface af_packet::replay (interface is down)

Also removes some code duplication and prepares for loopback
special casing.

Fixes #51
@awelzel awelzel force-pushed the topic/awelzel/maintenance-usability-and-duplicated-loopback-packets branch from bf4206c to 588d4aa Compare March 29, 2023 14:20
@timwoj timwoj requested a review from J-Gras March 29, 2023 17:07
...we'll see them as incoming again and only pass them up to
Zeek once this way. libpcap is doing it similarly, though
supporting V2 and V3.

Fixes #53
@awelzel awelzel force-pushed the topic/awelzel/maintenance-usability-and-duplicated-loopback-packets branch from bbab7d5 to 08719aa Compare March 29, 2023 17:54
Copy link
Collaborator

@J-Gras J-Gras left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The improved error messages will be helpful. Not sure the loopback change is worth it. This would be just for testing the plugin or is there an actual use case?

Comment on lines +295 to +315
// If this is a loopback interface and we're seeing an outgoing
// packet, drop it as it'll show up as incoming as well. Previously
// this would've caused Zeek to see all packets twice on loopback
// interfaces when compared to the normal libpcap based souce.
//
// The tpacket3_hdr is directly followed by a sockaddr_ll structure
// from where we can get the OUTGOING information about the packet.
//
// https://github.com/the-tcpdump-group/libpcap/blob/244080f5f9d4f17340041d1f5a3efd278ff08d7b/pcap-linux.c#L1173-L1181
if ( is_loopback )
{
const struct sockaddr_ll *sll = (struct sockaddr_ll*)
((uint8_t *)packet + TPACKET_ALIGN(sizeof(struct tpacket3_hdr)));

if ( sll->sll_pkttype == PACKET_OUTGOING )
{
DoneWithPacket();
continue;
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can see the point made here that it doesn't seem very elegant to introduce all this for a quite exotic edge case. Throwing a warning on startup seems to be a good idea. Let's go with the same behaviour Suricata ends up with.

Comment on lines +155 to +157
// std::fprintf(stderr, "AF_Packet: ifindex=%d ifr_flags=%0x is_loopback=%d\n",
// interface_ifindex, interface_flags, is_loopback);

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// std::fprintf(stderr, "AF_Packet: ifindex=%d ifr_flags=%0x is_loopback=%d\n",
// interface_ifindex, interface_flags, is_loopback);

@@ -106,10 +130,10 @@ void AF_PacketSource::Open()
Opened(props);
}

inline bool AF_PacketSource::BindInterface()
// Get ifindex and ifr_flags props.path.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// Get ifindex and ifr_flags props.path.
// Get interface index and flags.

@@ -57,6 +64,23 @@ void AF_PacketSource::Open()
return;
}

// QueryInterface will log an appropriate error and return false.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// QueryInterface will log an appropriate error and return false.

Nit: I am not a fan of the name QueryInterface as the method comes with side-effects. Returning the values seems cleaner to me. If we skip the loopback part, the members for caching can be removed completely.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we skip the loopback part, the members for caching can be removed completely.

Yeah, seemed nice to not duplicate the ioctl for getting the index, but sure can let go.

I'll re-spin without the loopback change and just keep the issue open.

@awelzel
Copy link
Contributor Author

awelzel commented Apr 3, 2023

Closing to re-spin without the loopback changes.

@awelzel awelzel closed this Apr 3, 2023
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.

Duplicated packets when listening on loopback interface Improve error message when interface is down
2 participants