sleinen / samplicator

Send copies of (UDP) datagrams to multiple receivers, with optional sampling and spoofing
GNU General Public License v2.0
389 stars 132 forks source link

FreeBSD 11 now requires the -s 0, -S no longer working #45

Closed lungdart closed 5 years ago

lungdart commented 7 years ago

On FreeBSD 11-RELEASE-p1 with samplicator 1.3.8.rc1

Running samplicator with the following syntax no longer works. No flows are captured $ samplicator -p <port> <target>/<port>

This however, does work $ samplicator -s 0 -p <port> <target>/<port>

Samplicator is also no longer able to spoof source address. This seems to be due to a change in FreeBSD 11 to no longer convert incoming packet headers ip_len and ip_off fields to host order. They now remain in network order with the rest of the packet header

lungdart commented 7 years ago

Here's the patch file I created to compile correctly from ports. (For spoof support, There's a work around for the source listen issue, so I didn't bother)

--- rawsend.c.orig  2017-02-13 13:51:16.373547000 +0000
+++ rawsend.c   2017-02-13 14:10:51.453719000 +0000
@@ -120,7 +120,7 @@
      BSD-derivatives require host byte order, but at least OpenBSD
      since version 2.1 uses network byte order.  Linux uses network
      byte order for all IP header fields. */
-#if defined (__linux__) || (defined (__OpenBSD__) && (OpenBSD > 199702))
+#if defined (__linux__) || (defined (__OpenBSD__) && (OpenBSD > 199702)) || (defined(__FreeBSD__) && (__FreeBSD__ > 10)) 
   ih.ip_len = htons (length);
   ih.ip_off = htons (0);
 #else
richardhkirkando commented 6 years ago

Hi, recently upgraded my server to FreeBSD 11. Could you clarify what your workaround for spoof support was?

lungdart commented 6 years ago

If the above patch file is no longer valid, you need to modify rawsend.c manually.

The section that has the following code changes some fields byte order.

#if defined (__linux__) || (defined (__OpenBSD__) && (OpenBSD > 199702))
  ih.ip_len = htons (length);
  ih.ip_off = htons (0);
#else

The problem is in FreeBSD 11.0, these fields order were changed at an operating system level, so now this section of code is required, but is not included at compile time due to the if statement.

Changing the above section's if statement to look like this, compiles the relevant code in:

#if defined (__linux__) || (defined (__OpenBSD__) && (OpenBSD > 199702)) || (defined(__FreeBSD__) && (__FreeBSD__ > 10)) 
  ih.ip_len = htons (length);
  ih.ip_off = htons (0);
#else

What I did to get this to work, was create a patch file, and include it as a patch in my local ports tree at /usr/ports/net/samplicator/files/patch-rawsend.c and install it using ports.

richardhkirkando commented 6 years ago

Thanks for the reply - your patched worked for me, I misunderstood and thought you had done something else in addition.

3fr61n commented 5 years ago

Hi guys,

I'm using a container with ubuntu 16.04, and I don't understand why spoofing is not working, it does not preserve source packet, I tried your workaround and still doesn't work

any ideas?

Thanks