Hi there sorry for disturbing you guys. But I read something in the Magazine about porting codes to IPV6 so i tried just changing this code (socket.AF_INET6, socket.SOCK_STREAM)
In python it works, but the problem is that the server does not display the client ip.
I expected it to display it like this. Got connection from ('127.0.0.1', 59815).
But for it , it messes up all thing and give me this (Got connection from ('::1', 59815, 0, 0)),
So if I ask were is the client IP here?. and what does the two last zeros(0, 0) really mean?. And what should i do to port my code to IPv6.? Thanks iam using python(geany)
So if I do this(socket.socket(socket.AF_INET6, socket.SOCK_STREAM)) will I have put my code to IPV6, o are there some other things I need to do thanks)
::1 is the IPv6 address for localhost, just like 127.0.0.1 is the IPv4 address for localhost. So you are seeing the client's IPv6 address.
The fields in the socket address are documented in the Python socket documentation. They are:
host
port
flowinfo
scope-id
Flowinfo and scope-id are new for IPv6. Flowinfo contains the Flow Label, which is specified in RFC 6437. If you don't know how to use it you can safely leave it at 0. The scope-id is used when an address is valid in multiple scopes. IPv6 link-local addresses for example are valid on every IPv6 interface, but routing them from one interface to another is not possible. So if you want to communicate with link-local addresses you have to specify which interface to use. The scope-id is the number of the interface.
When porting code to IPv6 you have to think about a few things. The socket handling you already have changed. You should also look at name resolving and use functions that support both IPv4 and IPv6 (i.e. don't use gethostbyname() but use getaddrinfo() etc.) And don't forget to allocate enough space when storing IP addresses. IPv6 addresses take up more space than IPv4 addresses.
PS: The IPy library provides very useful classes for dealing with IP addresses.
Related
I want to receive unicast UDP packets sent to my machine's IPv4 address only, ignoring broadcast packets. This works if I hardcode the IP address like sock.bind(('192.168.1.69', 9)) but to make this code portable, I need a way to find the machine's own IP. I tried the below code, which isn't working:
host = socket.gethostname()
socket.gethostbyname(host)
The second line fails with: socket.gaierror: [Errno 8] nodename nor servname provided, or not known
If I instead do sock.bind(('0.0.0.0', 9)) then it works, but it also receives broadcast packets sent to 255.255.255.255 which I don't want. Using SOCK_DGRAM strips out the IP headers, so I don't think it's possible to inspect the destination IP address.
Edit: On macOS (and probably linux) I can get the destination IP using sock.recvmsg() after enabling socket.IP_RECVDSTADDR, but this doesn't work on Windows, which is what I need.
To achieve this you need someone on the internet to tell you what is the public IP they see when you send them a package.
Check this thread provides some alternatives using services such as whatsmyip.org, api.ipify.org and ident.me.
Here is one example by #serge-stroobandt in the mentioned thread which is working for me:
import urllib.request
external_ip = urllib.request.urlopen('https://ident.me').read().decode('utf8')
print(external_ip)
Good luck!
Use the fully qualified domain name search.
import socket
hostname = socket.getfqdn()
socket.gethostbyname_ex(hostname)
Gives you information like
('F12234.mydom.com', [], ['xxx.19.xxx.1', '10.195.3.101'])
The last list of IP's are the IP's currently associated to the networks your are connected to. If you have only one network connected, it should be one.
I need my own IP in a small script and in order not to hardcode it, I`ve found a piece of code from here(stackoverflow) that works.
This--
with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as s:
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
--
What is not clear for me is why it only works on UDP and not TCP? It has something to do with the google dns server? Thanks in advance.
This has nothing to do with Google and nothing to do with DNS.
All what this code does is to "connect" a UDP socket to an external IP, so that the OS kernel figures out which local IP address it needs to use in order to reach this external system. This is no real connection, i.e. there is no traffic involved but the OS kernel is only checking routing tables and local interfaces in order to decide which IP address to use as source in case one would actually use the socket to send data.
One could do the same with TCP. But in this case a real TCP connection would be established which means that actual traffic would be exchanged and that the connect would fail if the external system would not be reachable on this port (i.e. no listener, firewall in between etc).
With UDP instead connect will not produce any traffic and would fail only if no route to the destination IP address could be determined. This also means that an arbitrary external IP address and port could be used, i.e. ('1.1.1.1',11) would work the same as ('8.8.8.8',80).
I am writing a socket program to create a simple server.
When I write ip = socket.gethostbyname(socket.gethostname()) and then I print ip it prints 127.0.1.1
Why does this keep happening?
My device is connected to a mobile hotspot connection still the ip address remains of a local host.
I am using ubuntu 19.04 OS
The problem is that a host has multiple interfaces. It is not a problem is you use a true DNS or a carefully handwritten /etc/host file because then the system will look there to find the translation. But depending on the configuration, the host name can be bound to all the available interfaces, including the loopback one. And gethostbyname returns the address of the first of those interfaces in its own order.
To make sure of that, you should use gethostbyname_ex which returns a list of all the interfaces, and you should find the hostspot connected one, in addition to the loopback one.
How do you lookup the local hostname from an IPv6 address in Python?
I'm trying to diagnose network bandwidth hogs, and I'm using Wireshark to find which IPv6 addresses are using the most bandwidth, but it doesn't include any hostsnames, so I'm left with a CSV of IPv6 addresses and total bytes transmitted.
Note, I'm not talking about converting a generic IP to domain, since that only works for DNS, not your local network's hostnames.
The only command line tool I know for doing this is:
sudo nmap -sn 192.168.1.0/24
but that doesn't list IPv6 addresses.
This is what I found looking online, I'm sorry but i think that what you are lookin at isn't possible.
From WireShark Q&A:
What you're looking at are probably neighbor discovery packets, which
are sent to a special multicast address called "solicited node
multicast".
It's basically the replacement mechanism for ARP, which is not used
for IPv6 anymore.
Usually, if you need to find out where something is coming from you
should try to determine the MAC address of the source, and then log in
to your switches to find the port where that MAC address is connected.
There should be a command that will show you the MAC address table of
the switch. If you can find a port where only the MAC address in
question is listed you need to follow the cable from that port to the
device.
If you have more than one MAC address listed for a port it is usually
a connection to another switch. In that case you need to log in to the
switch it connects to and repeat your search.
After allowing my raspberry pi to access port 9999 of my router socketname.bind(96.231.140.202,9999) in python gives me a cannot assign error
To port forward I used:
myfiosgateway.com/#/firewall/portforward (the same method
worked fo my apache server) and I have verified that 96.231.140.202 is my pub ip
You cannot bind to your public IP. Your router is doing that. You instead want to bind to your private IP and port forward traffic destined to 9999 to your bound IP on your pi, this address will fall into the rfc compliant private IP ranges, so it will most likely be something like 192.168.1.12 or something similar.
For example:
socketname.bind(0.0.0.0,9999) #the use of 0.0.0.0 will automatically find your available interface on that raspberry pi.
If you let me know exactly what socket library youa re using I can craft the exact code.