Sending IPv6 multicast packets through a specific network interface - python

I am trying to send IPv6 UDP packets to all of the nodes on the local network segment, in python, over Windows.
I have several network interfaces in my computer, and I want to know how to specify the network interface for sending the packets.
I have tried sending the packets to the multicast address ff02::1, using socket.sendto (without binding), but the packets are sent in the wrong network interface.
Any idea how can I specify the network adapter? (I read about BINDTODEVICE, but it won't work on windows, and some methods using bind to broadcast IP address classes, but only for IPv4).
Thanks!

According the answer to this question- multicasting with ff12::1 sometimes works better than multicasting with ff02::1.
I tried it and it worked- the packets were sent through the Ethernet network interface (as I wanted), and not in the WiFi as they were before.
However, I don't know why is it working, and I couldn't find any reference for it in the IPv6 RFC or anywhere else in the internet.
Explanations will be welcomed :)

I didn't really like the previous solution, so I kept looking for others.
The first option that worked for me is to bind the sender socket to the specific network interface address. The network interfaces addresses can be found using netifaces module, and I used this helpful answer to specify the Ethernet address.
Another option that might work is the IPV6_MULTICAST_IF option-
#x is the relevant interface index
sock.setsockopt(socket.IPPROTO_IPV6,socket.IPV6_MULTICAST_IF,x)
In Windows, python 2.7, one should add the line
socket.IPPROTO_IPV6=41
before this code (since the relevant enum is not well defined).
Additional information can be found here (Windows) or here (Linux).
Although it seems like a simpler solution, I didn't completely managed to make it work, and not sure what is the proper way to find the right interface index (on Windows, Linux has several options).

This is a problem with your system configuration. The operating system needs to be configured with the proper IPv6 routes to ensure the packets go out on the correct interface. It is not up to the application to decide, similar to how it is not the application's job to assign an IP address to the network interface - it's all the responsibility of the OS.
Here is an answer that explains how this is done under Linux. Feel free to add a comment with a link for how it's done on Windows if anyone knows.

Related

How can I capture the URL of the devices connected to my Network

I need help, information, ideas, advice on how I can capture the URLs accessed by the devices connected to my Network. Below I explain the case.
I have a device that bridges devices (cell phones or computers) and the Internet, the operating system of this device is Ubuntu 18, this is configured (not by me so I can not give more details). What I was asked for is a solution, which allows you to create continuous logs of the pages visited by the connected users and the time they are on these pages. I was also asked that the devices that connect through my bridge have to be registered with a username and password. (As well as some free Internet points in several countries). Then this information will be used to give a report to the teacher. The point is that I tried with Squid-Proxy and it is not what I am looking for because for this to work I must configure the search engines of each device separately and as it is evident I cannot do this.
Beforehand thank you very much.
P.S. If the solution could be in Python it would be great.
I believe this is a copy of https://stackoverflow.com/a/26516772/11392720
dpkt is an extensive tool (written in Python) for parsing TCP traffic, which includes support for decoding packets involved in the SSL handshake. Another tool for running and decoding captures from Python is pypcapfile.

Sending broadcast to all networks

I am currently writing a python program that needs to discover other instances of itself on LAN. It uses UDP broadcasts for discovery (255.255.255.255).
The problem is that if the computer has multiple network adapters (is connected to multiple networks) then only one of those networks will receive the broadcast. My initial idea was to enumerate through all network addresses assigned to local networks and send a broadcast packet for each one (for example 192.168.0.255 and 192.168.1.255). However, there seems to be no reliable way to detect all the local network addresses as everything I found and tried either relies on python-2-only library or returns only 127.0.1.1 on my linux virtual machine (which has 192.168.0.100 and some others).
How can I broadcast to all available networks in this case?
I'm using Python 3 and am looking for platform-independent way to do it, and without big third-party libraries. A library that correctly displays all network interfaces would do the job.
Try nmap. There is python-nmap here https://pypi.python.org/pypi/python-nmap for your needs
NOTE: the 0.2.7 version number is for python-nmap, not python itself, so it works in python3).
Interesting problem. However:
Until you have your application installed on every node don't expect answer from every machine in the network. For security reasons answering to broadcasts is forbidden in certain types of devices and systems.
You can try following code to obtain local addresses:
import socket
myips = socket.gethostbyname_ex(socket.gethostname())[2]
[ip for ip in myips if not ip.startswith("127.")][:1]
The problem with detecting the netmask set for that IP remains.
Use netifaces module available on pypi as well. Examples on the page are enough to explain how to use the module.

Python: how to calculate data received and send between two ipaddresses and ports

I guess it's socket programming. But I have never done socket programming expect for running the tutorial examples while learning Python. I need some more ideas to implement this.
What I specifically need is to run a monitoring program of a server which will poll or listen to traffic being exchange from different IPs across different popular ports. For example, how do I get data received and sent through port 80 of 192.168.1.10 and 192.168.1.1 ( which is the gateway).
I checked out a number of ready made tools like MRTG, Bwmon, Ntop etc but since we are looking at doing some specific pattern studies, we need to do data capturing within the program.
Idea is to monitor some popular ports and do a study of network traffic across some periods and compare them with some other data.
We would like to figure a way to do all this with Python....
You probably want to use scapy for that. Just sniff all ethernet traffic on a particular interface, drop everything that is not TCP and doesn't match the port.
Not sure if scapy can already track TCP connections (stuff like recognizing duplicate sequence numbers, extracting just the payload stream) but I would guess it probably can, and if not it's not too hard to hack together a good-enough TCP connection tracker that works for 95% of the traffic.
Alternatives would be to use sockets directly (look for raw sockets) or libpcap, which can both be done from Python. You may also want to check out the filter experssion syntax of the 'tcpdump' commandline tool, maybe it can do what you want already.
I bet there are more specialized high-level tools for this, but I don't know them.
PS: if you don't know wireshark yet, go check it out and play around with it first. It can follow TCP streams and will teach you what TCP connection tracking means. Maybe its commandline binary, tshark, can be used to extract TCP streams for what you want.
IPTraf is an ncurses based IP LAN monitoring tool. Has a capability to generate network statistics including TCP,UDP,ICMP and some more.
Since you're thinking to execute it from python, you may consider to use screen (screen manager with VT100/ANSI terminal emulation) to overcome ncurses issues and you may want to pass logging and interval parameters to IPTraf which forces iptraf to log to a file in a given interval. Little bit tricky but eventually you can have what you are looking for by basically parsing the log file.

Proper way to publish and find services on a LAN using Python

My app opens a TCP socket and waits for data from other users on the network using the same application. At the same time, it can broadcast data to a specified host on the network.
Currently, I need to manually enter the IP of the destination host to be able to send data. I want to be able to find a list of all hosts running the application and have the user pick which host to broadcast data to.
Is Bonjour/ZeroConf the right route to go to accomplish this? (I'd like it to cross-platform OSX/Win/*Nix)
it can broadcast data to a specified host on the network
This is a non-sequitur.
I'm presuming that you don't actually mean broadcast, you mean Unicast or just "send"?
Is Bonjour/ZeroConf the right route to go to accomplish this?
This really depends on your target environment and what your application is intended to do.
As Ignacio points out, you need to install the Apple software on Windows for Zeroconf/mDNS to work at the moment.
This might be suitable for small office / home use.
However larger networks may have Layer 2 Multicast disabled for a variety of reasons, at which point your app might be in trouble.
If you want it to work in the enterprise environment, then some configuration is required, but that doesn't have to be done at the edge (in the app client instances).
Could be via a DHCP option, or by DNS service records.. in these cases you'd possibly be writing a queryable server to track active clients.. much like a BitTorrent Tracker.
Two things to consider while designing your networked app:
Would there ever be reason to run more than one "installation" of your application on a network?
Always consider the implications of versioning: One client is more up to date than another, can they still talk to each other or at least fail gracefully?
Zeroconf/DNS-SD is an excellent idea in this case. It's provided by Bonjour on OS X and Windows (but must be installed separately or as part of an Apple product on Windows), and by Avahi on FOSS *nix.
I think that ZeroConf is a very good start. You may find this document useful.
I have a list on a webpage, nice if you need internet communications.
<dl_service updated="2010-12-03 11:55:40+01:00">
<client name="internal" ip="10.0.23.234" external_ip="1.1.1.1"/>
<client name="bigone" ip="2.2.2.2" external_ip="2.2.2.2">
<messsage type="connect" from="Bigone" to="internal" />
</client>
</dl_service>
My initial idea was to add firewall punching and all that, but I just couldn't be bothered too many of the hosts where using external IPs for it to be a problem..
But I really recommend Zeroconf, at least if you use Linux+MacOSX, don't know about Windows at all.

Network Communication program in python

Basically what I'm trying to achieve is a program which allow users to connect to a each other over a network in, essentially, a chat room. What I'm currently struggling with is writing the code so that the users can connect to each other without knowing the IP-address of the computer that the other users are using or knowing the IP-address of a server.
Does anyone know of a way in which I could simply have all of the users scan the IP range of my network in order to find any active 'room' and then give the user a chance to connect to it?
Also, the hope is that there will be no need for a central server to run this from, rather every user will simply be connected to all other user, essentially being the server and client at the same time.
I can give you two suggestions. First of all, UDP packets to the broadcast address of your network will be received by everybody. Secondly, there is a protocol for programs offering certain services to find each other on a local network. That protocol is called mDNS, ZeroConf, or Bonjour.
Using broadcast UDP is likely going to be the faster route. But if I were you, I'd learn how to use ZeroConf instead. It's supported well under IPv6 and already used by several interesting programs such as SubEthaEdit and Gobby.
Here is a link to a nice tutorial for implementing something that speaks ZeroConf in Python.
Another recommendation... If you want to hand roll your own broadcast/multicast UDP code and you can be sure that all of the systems you're on are running a Linux that's newer than 2003 or so, and all the Windows systems are XP or better, you can probably get away with using IPv6. The IPv6 link-local (think same LAN) all hosts multicast address is ff02::1. That's really simple and easy, and it will reach all the other systems on the same LAN. It's much better than having to figure out what your network's broadcast address is with IPv4.

Categories

Resources