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

Adding support to spoof ipv6 #37

Open dkhenry opened 8 years ago

dkhenry commented 8 years ago

Samplicator can now spoof IPv6 packes as well as IPv4 packets.

sleinen commented 8 years ago

Thanks for your patch. I'll try to review it soon.

On which systems did you test this?

dkhenry commented 8 years ago

This was mainly developed on OSX El Capatian, and then was tested on CentOS 7 and a Gentoo based system running a 3.18.34 kernel. To compile on Linux you need to run configure with

CFLAGS=-D_GNU_SOURCE

as the in6_pktinfo struct is guarded for some reason in glibc.

The OSX only implementation was a little cleaner, as I was still using a SOCK_RAW and writing out the UDP header and calculating the checksums, but when I switched to Linux the sendmsg syscall was throwing a EINVAL so I switched to a SOCK_DGRAM and stopped writing the UDP header.

dkhenry commented 8 years ago

This would close #16

dkhenry commented 8 years ago

One thing a tester noticed for this was the spoofing does not work with IPv6 mapped IPv4 addresses. This appears to be a limitation of the Linux networking stack to not accept IPV6_PKTINFO metadata for those kinds of addresses.

boberlla commented 7 years ago

We have been using this in production for months now and there are no problems with it. dkhenry is no longer with our company but we would like to get this merged-in.

sir-galahad commented 6 years ago

Does linux need some special configuration for this? I haven't been able to get this to work on centos, debian, or raspian :/

indirakas commented 3 years ago

@dkhenry Which flag in the samplicate command did you use to indicate it to listen to ipv6 addresses?

dkhenry commented 3 years ago

Hi @indirakas you don't have to give any command to listen on ipv6, this patch allows you to spoof ipv6 addresses when you send out the packets, without it you will always send packets as the samplicator host IP

pwefel commented 3 years ago

@dkhenry Hello, I work with Indira and we are trying to implement your wonderful patch to enable spoofing for ipv6. Did you happen to also modify rawsend.h? When we compile we get a problem with struct in6_pktinfo.

rawsend.c:178:41: error: invalid application of ‘sizeof’ to incomplete type ‘struct in6_pktinfo’ size_t cmsglen = CMSG_SPACE (sizeof (struct in6_pktinfo));

I'm not a C coder but I wonder if in6_pktinfo needs to be declared somewhere? and similarly with this error too.

rawsend.c:187:11: error: dereferencing pointer to incomplete type pktinfo->ipi6_ifindex = 0;

Thank you!

dkhenry commented 3 years ago

@pwefel did you compile it with CFLAGS=-D_GNU_SOURCE at some point glibc gated that struct on that define

pwefel commented 3 years ago

@dkhenry Bingo! that did the trick. Thank you so much. (I guess I should have seen the note at the beginning of this thread )

pwefel commented 3 years ago

@dkhenry We are close, but something is still not right. Running from the cli with -S option fails to send. Removing the -S option works but uses the default port of 2000 and without spoofing the source IP. Any ideas on this? Below is the output with and without -S (using -d for debug) and the contents of the .conf file

[root@collect-west samplicator]# ./samplicate -S -6 -d 1 -p 40033 -c /usr/local/esnet/var/samplicator/samplicator13.conf received 1112 bytes from 2001:400:0:40::200:172:50252 socket error: 0 socket: Invalid argument sending datagram to 2001:400:210:155::61:2000 failed: Invalid argument ^C [root@collect-west samplicator]# ./samplicate -6 -d 1 -p 40033 -c /usr/local/esnet/var/samplicator/samplicator13.conf received 832 bytes from 2001:400:0:40::200:172:50252 sent to 2001:400:210:155::61:2000

[root@collect-west samplicator]# cat samplicator13.conf

Thanks.

dkhenry commented 3 years ago

for the conf file it looks like you have the format wrong, its expecting a / not a :

As for. the spoofing, I do remember that on some systems the kernel wouldn't allow you to spoof this way. I believe it was OSX that prohibited you from sending spoofed ipv6 unless you used lower level methods.

indirakas commented 3 years ago

Is this a correct format then: [::]/0: [2001:400:210:155::61]/9996 or

dkhenry commented 3 years ago

I believe the first way is.

On Thu, Apr 29, 2021, 9:01 PM indirakas @.***> wrote:

Is this a correct format then: [::]/0: [2001:400:210:155::61]/9996 or

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/sleinen/samplicator/pull/37#issuecomment-829788395, or unsubscribe https://github.com/notifications/unsubscribe-auth/AADXRK7E7J26L3EJ6GMCMYTTLITQ7ANCNFSM4CI56V3A .

indirakas commented 3 years ago

It is still failing then with the "Invalid argument" error: 2021-04-29T21:28:46.944080-07:00 samplicate: socket error: 0 2021-04-29T21:28:46.944267-07:00 samplicate: socket: Invalid argument 2021-04-29T21:28:46.944452-07:00 samplicate: sending datagram to 2001:400:210:155::61:2000 failed: Invalid argument

arjenz commented 2 years ago

@indirakas On newer kernels an extra setsockopt setting IP_FREEBIND appears to be necessary, see my PR against this PR, https://github.com/sleinen/samplicator/pull/76