Multicast listening and interface IP address change - c

I am binding to a multicast group and port to listen a multicast stream. Since adding the group membership (via IP_ADD_MEMBERSHIP) requires specifying a specific network interface, what will happen when that interface IP address changes?
Do I have start again with a new socket and add membership? This is related to Linux/C environment. I do see some packets comming in without changing IP, but I feel I have to restart.
thanks,
gl

The Linux kernel appears to be tracking the interface based on the interface identifier rather than the interface IP address. From a couple of experiments, it looks like your application won't need to have any special handling
Experiment 1: Host Receiving
Here's an experiment I put together with Ubuntu to test if the host will continue to receive across the interface IP change.
$ uname -a
$ Linux joel-VirtualBox 3.16.0-34-generic #47-Ubuntu SMP Fri Apr 10 18:02:58 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
I have a simple Python test script for running a multicast receiver on a network interface eth2, identified by static IP 192.168.33.11:
import socket
import struct
sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP )
sock.bind( ('',50400) )
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, socket.inet_aton('239.254.2.4') + socket.inet_aton('192.168.33.11') )
while True:
print sock.recv( 2048 )
sock.close( sock )
Once running the python script, I can verify the membership by running:
$ netstat -gn
lo 1 224.0.0.1
eth0 1 224.0.0.251
eth0 1 224.0.0.1
eth1 1 224.0.0.1
eth2 1 224.0.0.251
eth2 1 239.254.2.4
eth2 1 224.0.0.1
From another PC, I ran a multicast sender, sending to 239.254.2.4:50400 and verified the data is printed. I then changed the static IP to 192.168.33.12 and verified the membership is still reported by netstat and my python script can continue to receive data.
Experiment 2: IGMP Membership Reports
I put another experiment together to see what happens to the IGMP membership reports:
As you can see when the change of IP address happens, no new IGMP report for 239.254.2.4 is generated. But when the script is killed, an IGMP Leave message is sent.
This could be considered "a hole" though any switch or router that is performing IGMP snooping or multicast routing will be periodically issuing IGMP queries. Our host will respond to this query by sending its current memberships (including the membership for 239.254.2.4).

I don't think you have to rejoin the group. Both the localhost and the router only have a count of members, and in both cases if it's non-zero it will deliver the multicast internally. But I could be wrong.

Related

Ettercap - ARP poisoning unsuccessful

Yesterday I successfully performed a MITM attack by ARP poisoning between my router and my Windows7 computer. I used Ettercap on a Linux machine.
However, today, running the same command does not work anymore. It looks like Ettercap cannot reach my computer, which IP is 192.168.0.17.
Here is what I got :
We can see that the only host added to the list is the router one (192.168.0.1)... What I don't understand is that it was working few hours ago.
I noticed also another thing.
using the command
sudo arpspoof -i wlp20s0 -t 192.168.0.17 192.168.0.1
The ARP poisonning DOES work this time. But now the problem is that it is acting like a DDOS on my victim... It completely loses internet connection.
And before it was not, it was working as expected.
So I guess something has changed on my victim computer but I cannot figure what.
Thank you.
IP forwarding is the ability for an operating system to accept incoming network packets on one interface, recognize that it is not meant for the system itself, but that it should be passed on to another network, and then forwards it accordingly.
From https://openvpn.net/faq/what-is-and-how-do-i-enable-ip-forwarding-on-linux/
When you perform MITM packets that don't match your IP are being sent to you and are not passed on correctly so the victim can reach out to the internet. With IP forwarding enabled your computer will reroute the packets correctly and the attacked computer will have access to the internet.
On Linux if I remember correctly:
echo 1 > /proc/sys/net/ipv4/ip_forward
will fo the job.
Arp replies are stored in cache, so first of all do some tricks here:
Remove arp cache from windpws with cmd.
(Cause the first priority is the cache and if host cant find the mac address it will generate an ARP request,then your router will repliy with ARP reply)
issue this command to see arp table:
arp -a
When you do Mitm with arp spoof and your computer looses internet connectivity it might be your DNS misconfiguration.
You ll need to enable dns server.
(If wan to brows web pages)
Try to do it with ettercap and enable arp poision and dns spoof module.

Linux use interface for raw socket only

I'm having a OpenWrt Linux distribution for my embedded system. The device has 3 network interfaces: eth0, eth1 and wlan0.
One of the network interface (eth0) should be used for raw socket programming only. I'm able to create a socket with the parameters AF_PACKET, SOCK_RAW, ETH_P_ALL. The socket receives all network traffic, I can send packets and everything is OK.
But my problem is, that the OS is also using the interface for sending an reciving (e. g. ARP and ICMP requests/responses).
Is there any option that the interface is only used by my program and not by the OS itself?
This is not possible to achieve with a vanilla kernel. But this can come close:
First, ignore all arp requests on that interface:
echo 8 > /proc/sys/net/ipv4/conf/eth0/arp_ignore
Then, disable IPv6:
echo 1 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6
Finally, filter all IPv4 packets coming on that interface
iptables -I INPUT -i eth0 -j DROP
And do not set an IP-address or routes on that interface. This is of course not perfect, certain packets will still be processed by the kernel, but I don't think there is a much better solution.

ARM MBED CoAP example mot opening port

I have succesfully built the CoAP protocol example for ARM mbed (https://developer.mbed.org/teams/sandbox/code/coap-example/file/0681e205d0e9/) on a K64F board. It comes out of the box, except for the server name (coap.me) changed to an internal IP address.
I see that it runs correctly and connects to the network:
[EasyConnect] Using Ethernet
[EasyConnect] Connected to Network successfully
[EasyConnect] IP address 192.168.1.15
[EasyConnect] MAC address 0e:43:54:d9:7c:71
Connected to the network. Opening a socket...
Calculated message length: 11 bytes
Starting server
Sent 11 bytes to coap://192.168.1.10:5683
I have set a computer that can connect to it. It can ping correctly to the board and I see that the ARP is negotiating with the correct MAC address.
I have launched an NMAP test and I see that the port is closed:
PORT STATE SERVICE
5683/udp closed unknown
If I set a CoAP client in the computer (Copper) I see no connection in the terminal.
What I am missing?
Moving this to the answer section as well, in case someone else runs into this problem.
If you want to use an mbed OS 5 device as a UDP server, make sure to call .bind() on the socket.

Prevent from getpeername() to return 127.0.0.1

I have a Server (A) and a client (B), written in C, running on the same Linux machine.
The server binds a port to INADDR_ANY, and the client binds another port to INADDR_ANY.
When another client (C), which is running on another Linux machine, connects to the server, I want the server to get the IP address of client B and send it to client C.
When I'm using getpeername() from the server, it returns "127.0.0.1" which is correct, but I can't send this address to client C- it won't be able to connect to client B with that address.
Is there any smart way to get the actual IP of client B?
If it is somewhat easier, I can make each client send it's IP to the server.
Thanks!
Use getifaddrs() to get the interface IP address, there's an example in the man page. Note that you can send the IP address of any interface since the server is bound using INADDR_ANY so it listens on all interfaces. From man ip(7)
When INADDR_ANY is specified in the bind call, the socket will be
bound to all local interfaces.
If you want the public IP address then refer to this question:
Get public/external IP address?
What you actually want to know is the IP address of the interface, which would be used to route towards client C.
With the Linux command line, you can do this (assuming C is 10.0.0.1):
# ip route show match 10.0.0.1
default via 20.0.0.2 dev eth0
# ifconfig eth0
eth0 Link encap:Ethernet HWaddr 00:00:00:00:00:00
inet addr:20.0.0.3 Bcast:20.0.0.255 Mask:255.255.255.0
In this case, you'll want to use 20.0.0.3.
The question remains how to get all this in C.
One way would be to connect to some service on C, and run getsockname on the resulting socket.

Discovering DHCP servers using multicast (224.0.0.12) in GNU/Linux/C

This question might stem from a fundamental misunderstanding of IP multicast, so please correct me if I'm off base.
I'm trying to write C code to find the IP address of all the DHCP servers on the network. The use case is this:
Client broadcasts DHCP discover.
My proprietary relay agent picks up the packet, adds some essential information, and forwards it UNICAST to the DHCP server at a known IP address.
The problem I'm having is telling the relay agent where the DHCP server(s) is(are). I found that multicast address 224.0.0.12 is reserved by IANA for DHCP servers, so I figured I'd just configure the servers to listen for that multicast traffic. But whenever I configure a linux socket option to IP_ADD_MEMBERSHIP to 224.0.0.12, it uses IGMP, which is an entirely separate protocol which I don't want to have to implement.
Am I just misunderstanding how multicast works? Shouldn't I be able to send a ping from the relay agent to 224.0.0.12 and have it return a ping response from all DHCP servers?
Additional Info:
the interfaces on all the boxes do have MULTICAST listed when I do an ifconfig
I have added the multicast route using ip route add 224.0.0.0/4 dev eth0 on all boxes
Perhaps you should do what clients do - broadcast (not multicast!) on the target network with a DHCPDISCOVER packet? I have a couple of running, working DHCP servers and none of them are listening on the 224 network.
You'll probably also want to either request your existing address, or send along a DHCPRELEASE for any offers you get back, so as not to tie up addresses in fake reservations on the servers.
In a general IPv4 setting use broadcast to UDP port 67, not multicast. The broadcast request should be answered by all DHCP servers on your network. Take a look at the details explained on the Wikipedia page or read the broadcast explanation in RFC 2131, Section 3. Also see this thread.

Resources