socket.gethostname() returning wrong host name - python

When I was setting up my Macbook Pro I changed my hostname I guess to my name Tristan. I'm trying to work with sockets and call:
socket.gethostbyname(socket.gethostname())
It is not giving me the error socket.gaierror: [Errno 8] nodename nor servname provided, or not known
I'm assuming this is an issue because I have changed the name. If I type:
socket.gethostname('Tristan.local')
It actually prints out the correct ip address. My friend's Mac has not had the hostname changed and it returns the address of the network she is on. How do I change my hostname back to the local hostname or whatever I need to do in order to make:
socket.gethostbyname(socket.gethostname())
Work again? I thought I was being fun at the time by changing it to my name but now I'm full of regret.

gethostname generally just reports what /etc/hostname or equivalent has in it, and that can be just a made up name. gethostbyname tries to resolve that name, and unless it's also in something like /etc/hosts, which some systems set up to match, and it's not resolvable by your configured DNS servers, then you get an error.
So you can try either fixing the name in /etc/hosts if it was there first under the old name, or you can ignore that and just use your host-name as-is.
Remember, unless your public and private IP match that DNS result is useless anyway. What you probably want is to hit a service like Ipify to determine what your actual external IP is.

Related

Python SMTP library can't handle IPv6

How can i add IPv6 option on SMTP library please ?
When i try to connect to SMTP using IPv6 i got this error :
smtpserver = smtplib.SMTP("smtp.gmail.com", 587, source_address=('2a00:xxxx:5::1e7', 80, 0, 0))
Error : TypeError: AF_INET address must be a pair (host, port)
Which means smtplib.py doesn't support IPv6
I found an article about that "https://bugs.python.org/issue3461" . I tried to add the patch into my smtplib.py but it didn't work
Can anyone please help me to do this ?
... source_address=('2a00:xxxx:5::1e7', 80, ...
The error message is misleading. Doing an strace on Linux shows that it actually tries to bind to the given IP and port but fails - and then issues this misleading error message. Why it fails can have various reason, but typical cases might be that it is no permission to bid to the port (binding to port 80 as done here needs root privileges) or that the port is already in use by another socket (port 80 is usually used for web servers).
In general it is better to only specify the IP address and leave the port to 0. This way it will use the given IP address as source IP but pick a random (ephemeral) port as source port.
I found an article about that "https://bugs.python.org/issue3461"
This is unrelated. It is only about the sender shown in the EHLO command during the SMTP dialog. If this is a problem just give the value to use with the local_hostname argument.
Python 3's socket.create_connection obtains the first DNS resolution entry of the target address that is connectable (and this is a behaviour that is documented in Python as unstable by the DNS design).
https://github.com/python/cpython/blob/fdcb675e/Lib/socket.py#L824
The CPython implementation _socket.connect throws the error in question on seeing a mismatch between the socket's address family at create time and the address family at another time,
https://github.com/python/cpython/blob/1aa6be0/Modules/socketmodule.c#L1807
Looking closer at socket.create_connection, I guess the source_address parameter cannot control the address family to use for the target. The socket object sock is created in create_connection with the address family of the resolved target address. Then source_address is used to specify the object's source with a call to sock.bind(source_address). It appears that at this point, if the resolved target was IPv4 but source_address was IPv6, the error is thrown?
As a possible fix that would not monkey-patch socket.create_connection, I can imagine that instead of providing a symbolic host name in the target address, the caller resolves the host name first to an A or an AAAA entry, depending on the desired family. The caller supplies the numeric recod as the target address. The source address's family should be in accord with the desired family, too.
In other words, the caller can use socket.getaddrinfo to find the required target address by the desired family. Other callers such as users of the request library can hot-wire socket.create_connection with the same idea.
https://docs.python.org/3/library/socket.html#socket.getaddrinfo

Connecting to BACnet device giving single use socket address error

I've tried to look through posts to see if i could find anything but haven't managed to find it yet.
I'm running the SCADA BACnet device simulator on my localhost.I'm assuming the ip for the device is my localhost ip since the only IP i could find was in the deviceAddressBinding property which showed 192.168.x.xx
I am running through the bacpypes(python library for bacnet) tutorial for the SampleApplication and when I first tried running the tutorial, it stated that my .ini file ip is not a valid address in the context. So I tried to put in the simulator's settings to try and connect to the simulator and now it's giving me a Only one usage of each socket address (protocol/network address/port) is normally permitted error. Not quite sure where to go from here, am I perhaps missing something?
my .ini file:
[BACpypes]
objectName: Testing Device
address: 192.168.x.xx #tutorial came with 128.253.109.40/20
objectIdentifier: 123
maxApduLengthAccepted: 1024
segmentationSupported: segmentedBoth
vendorIdentifier: 123
foreignPort: 47808
foreignBBMD: 192.168.1.254
foreignTTL: 30
My simulator properties:
it seems to be a windows issue. Replaced :
this_application = WhoIsIAmApplication(this_device, args.ini.address)
with:
this_application = WhoIsIAmApplication(this_device, ('', 47808))
your sample application and BACnet simulators are opening a server socket. looks like both are using the same port number. you can change the port number in ini file as given below
address: 192.168.1.22:47809
by default the BACPypes sample applications run on the 47808 port number unless you explicitly mention in the configuration file.

socket.gethostbyaddr() returns error on some computers and not for others

I've looked for any other threads related to this topic, but after an extensive search i was not able to find an answer that relates to my question. Using Python, I'm trying to use socket.gethostbyaddr("ip here") to determine the hostname of an ip address in a local network:
import socket
def gethostname(ip):
hostname = socket.gethostbyaddr(ip)
return hostname
For some computers (such as the server) this returns the triplet of hostname, alias and other IP's, but for others it does not. Instead, i get the following error:
socket.herror: [Errno 4] No address associated with name
What exactly does this error imply? What could it be that causes it? Is there any service or instane that should be running on the target computer in order for this to work? The computers i'm trying to get the hostname of run Debian.
If this question has already been asked then i am sorry, but i could not find it.
If it has something to do with reverse dns lookups, how would i solve this?
It means exactly what it says, there is no address associated. Not all IP addresses have a reverse-lookup address.

How to solve Python Sockets/SocketServer Connection [Errno 10048] & [Errno 10049]?

I'm trying to make an online FPS game and so far it works on my local network. What I'm trying to do is make it work globally
I've tried making other Python projects work globally in the past but so far I haven't been able to get it to work. I get my IP from ipchicken or whatever and put it as the HOST for the server, but when I try to start it I get this.
socket.error: [Errno 10049] The requested address is not valid in its context
I've tried many different versions of what could be my IP address found from various different places, but all of them give that output.
I thought, since I had my webspace, I could try doing what it says you can do in the Python manual:
where host is a string representing either a hostname in Internet domain notation like 'daring.cwi.nl'
So, I put in the domain of my webspace (h4rtland.p3dp.com) and I get this error:
socket.error: [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted
Though only on port 80, anything else gives me the same error as before.
If anybody can shed some light on this subject for me it would be greatly appreciated.
First off, port 80 is typically http traffic. Anything under port 5000 is priviledged which means you really don't want to assign your server to this port unless you absolutely know what you are doing... Following is a simple way to set up a server socket to accept listen...
import socket
host = None #will determine your available interfaces and assign this dynamically
port = 5001 #just choose a number > 5000
for socket_information in socket.getaddrinfo(host, port, socket.AF_INET, socket.SOCK_STREAM):
(family, type, prototype, name, socket_address) = socket_information
sock = socket.socket(family, type, prototype)
sock.bind(socket_address)
max_clients = 1
sock.listen(max_clients)
connection, address = sock.accept()
print 'Client has connected:', address
connection.send('Goodbye!')
connection.close()
This is a TCP connection, for an FPS game you likely want to look into using UDP such that dropped packets don't impact performance terribly... Goodluck

Availability of IP Address - Python

How to check the availability of an IP address in python?
For example, I wan't to change my system's IP address to 192.168.112.226 statically overriding the dhcp provided address. The default gateway is 192.168.112.1. But I wan't to check before if anyone is using 192.168.112.226 before assigning to myself.
Usually do this in command line from bash. I check with ping 192.168.112.226. If host is unreachable, I use 'ifconfig' and 'route' to assign it to myself.
How to automate this using python?
PS: I prefer python so that I can use python-notify to beautify the output whether success or failure.
This is so bad in so many ways I can't even explain how awfull this is.
Why do you want this? Could you please tell us that, and we could come up with a much better answer than this utterly uggly "sollution"?
If you have a Linux/Unix system, you can make your DHCP client to request the DHCP-server to give you a specific IP address if the DHCP server know it's free. How to do this depends on the distribution.
There are two problems I see that you will create with your "sollution".
As some other has written, you could check to see that the IP is "free" right now, but the machine that own that IP address might start right after your test. Using its IP address, wich you have kidnapped.
If the DHCP server don't know that you have kidnapped an IP address, it could give it out to someone else.
Whatever it will break the network for that computer and yours, generating lots of work, and possible anger for/to the network administrator. And you don't want that, do you?
Okay, if you want to use bash, you can import os module or subprocess module.
for example:
import os
command = os.system('pint 192.168.112.226')
if command == 0: #Sucess
#write os.system() and give it ifconfig and route commands as parameter.
else: print "This IP is used by another person in your network."
you can read more about os.system and subprocess in python, by importing them and writing help(subprocess) for example.
You can use socket.gethostbyaddr() to find if IP Address is being in use or not.
import sys, os, socket
# Stores the IP Address
ip_address = sys.argv[1]
try:
socket.gethostbyaddr(ip_address)
# If previous line doesn't throw exception, IP address is being used by someone
print "No"
except socket.herror:
# socket.gethostbyaddr() throws error, so IP is not being used at present
# You can write os.system() and give it ifconfig and route commands as parameter.
print "Yes"
The problem with this code is that method.gethostbyaddr() takes lot of time to throw socket.herror if IP address is not in use on the network.
If you name this script as isIPAvailable.py, then it can be called by:
python isIPAvailable.py 192.168.112.226

Categories