I am new to Python and having issues calling a variable from one func to use in another.
First function gets localhost IP, second function I would like to grab that IP and use it to port scan itself.
My open port function comes up with error 'AttributeError: 'function' object has no attribute 'ipv4''
Any help is greatly appreciated.
def get_IP():
ip = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip.connect(("8.8.8.8", 80))
print(ip.getsockname()[0])
ipv4 = ip.getsockname()[0]
ip.close()
return ipv4
def get_open_ports():
for port in range(1,65535):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.setdefaulttimeout(1)
result = s.connect_ex((get_IP.ipv4, port))
if result ==0:
print(f"Port {port} is open")
s.close()
You can pass it as an argument to the second function using the syntax:
def get_open_ports(my_ip):
But you need to call the functions:
ip = get_IP()
open_ports = get_open_ports(ip)
Or even
open_ports = get_open_ports(get_IP())
Related
It just times out for me , even if I use the gethostbyname method or gethostname for the private ip address....
Code:
def connect(self):
nm = nmap.PortScanner()
nm.scan(hosts = '192.168.1.0/24', arguments = '-n -sP -PE -PA21,23,80,3389')
devices = []
hosts_list = [(x,nm[x]['status']['state']) for x in nm.all_hosts()]
for ip,state in hosts_list:
devices.append(ip)
for ip in devices:
print(ip, type(ip))
try:
client_socket = socket.socket()
client_socket.settimeout(2)
try:
client_socket.connect((ip, self.port))
if type(client_socket) != None:
client_socket.send('hi'.encode())
client_socket.settimeout(None)
return client_socket
except Exception as e:
print(e)
except socket.error:
pass
When it gets to the correct Ip, it just... times out. Thought I had a problem with the function, but it appeared to not be the case.
TLDR- made a LAN automatic connecting using Nmap, the only thing it's connecting to is timeouts and my sadness D:
Edit: lemme show you the errors which occur when I run this function:
server:
server_socket = socket.socket()
hostname = socket.gethostname()
local_ip = socket.gethostbyname(hostname)
server_socket.bind((local_ip,self.port))
both sides decide the port which they want to use, i use socket.gethostbyname for server ip.
I have this short program:
import sys
import socket
target = "google.co.uk"
port = 443
print(target)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(target)
print("successfull connection to: " + target)
When I run the code, I get:
s.connect(target)
TypeError: getsockaddrarg: AF_INET address must be tuple, not str
When I tried to change the line to: s.connect(target,443)
I also got an error:
s.connect(target,443)
TypeError: connect() takes exactly one argument (2 given)
What is the problem?
What the function receives as a parameter is a tuple and thus a tuple should be given as a parameter. Meaning instead f(a,b) call the function with f((a,b))
And so, we fix your code like this:
import sys
import socket
target = "google.co.uk"
port = 443
print(target)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((target, port))
print("successfull connection to: " + target)
I was getting the same error. From the connections.py file from PyMySQL there's a function named connect() line with
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
sock.settimeout(self.connect_timeout)
sock.connect(self.unix_socket)
A Windows user will get
AttributeError: module 'socket' has no attribute 'AF_UNIX'
To fix it one should change the first line to
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
This will then get
File "C:\Users\tiago\Desktop\dev\venv\lib\site-packages\pymysql\connections.py", line 609, in connect
sock.connect(self.windows_socket)
TypeError: connect(): AF_INET address must be tuple, not str
Based on this answer, one just need to have the third line changed to
sock.connect((self.unix_socket))
so you should have
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.settimeout(self.connect_timeout)
sock.connect((self.unix_socket))
From the python library 'socket' is there a method that returns the IP of the socket that got binded to it?
Suppose a socket was declared and initialized like:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.connect(ip, port)
And I wanted to find the IP of a received datagram from a socket:
while True:
for s in socks:
recv = s.recv(1024)
#get ip of s or socket
#print received data from s.gethostname()
How would I go on about this?
you can try with recvfrom this method returns data and the address of the sender
data, address = sock.recvfrom(4)
Try with socket.getpeername().
Simple way would be like
data, (ip, port) = sock.recvfrom(4096)
print (ip)
I have a python class which grabs the IP address of the local machine you are on. It works on actual hardware (unless it's MacOS with bridged devices involved), or local VMs. This is the code:
class IPAddress:
ip_address = None
def __init__(self):
return
def _get_interface_ip(self,ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(s.fileno(), 0x8915, struct.pack('256s',
ifname[:15]))[20:24])
# does not work on MacOS with bridged devices such as vboxnet0, tap0, tun0
def get_lan_ip(self):
hostname = socket.gethostname()
ip = u''
try:
ip = socket.gethostbyname(hostname)
except socket.gaierror, e:
try:
ip = socket.gethostbyname(u'localhost')
except: pass
if ip.startswith("127.") and os.name != "nt":
interfaces = [
"eth0",
"eth1",
"eth2",
"en0",
"en1",
"en2",
"wlan0",
"wlan1",
"wifi0",
"ath0",
"ath1",
"ppp0",
]
for ifname in interfaces:
try:
ip = self._get_interface_ip(ifname)
break
except IOError:
pass
return ip
# Find out this instance
x = IPAddress()
server_ip = x.get_lan_ip()
This works everywhere it seems except on AWS. On AWS ifconfig eth0 gives the internal IP address assigned to eth0, whereas the class gives the external CNAME'd IP address associated with accessing the instance (in EC2 Classic).
What gives? Is there a better way to do self discovery with (for example) boto?
First, I wouldn't use gethostbyname() or its kin. Doing so relies upon external databases that you do not control, and that are often not up to date.
Next, I wouldn't call ioctl(). The existence of any particular ioctl, much less its behavior, is not standardized across operating systems.
If it were me, I would connect() to some external service and then call socket.getsockname():
def get_my_addr():
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(('8.8.8.8', 53))
return s.getsockname()[0]
If that didn't work, I'd connect() to a TCP-based service:
def get_my_addr():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect(('www.google.com', 80))
return s.getsockname()[0]
I am kind of new to python. I am currently trying to make and use a list/array of sockets in a program. So I have declared an array as follows:
myCSocks = ['CSock1', 'CSock2', 'CSock3', 'CSock4', 'CSock5']
And I am trying to use my array elements as follows:
myCSocks[i], addr = serverSocket.accept()
message = myCSocks[i].recv(1024)
I am getting the following error:
Traceback (most recent call last):
File "./htmlserv_multi.py", line 22, in <module>
message = myCSocks[i].recv(1024)
AttributeError: 'str' object has no attribute 'recv'
This kind of makes sense to me, it is saying that my array elements are of type String and are not sockets. So I understand what my problem is but I do not know how to remedy it. I have googled "list of sockets python" but did not find anything. Any help will be greatly appreciated. Thank you.
PS: My final objective is to create a very simple multithreaded TCP web server (using python)
CODE:
#! /usr/bin/env python
from socket import *
#does this work?
myCSocks = []
serverSocket = socket(AF_INET, SOCK_STREAM)
serverSocket.bind(('192.168.1.4',12000))
serverSocket.listen(5)
while True:
for i in range(0, len(myCSocks)+1):
myCSocks[i], addr = serverSocket.accept()
try:
for i in range(0, len(myCSocks)):
message = myCSocks[i].recv(1024)
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.read()
myCSocks[i].send('HTTP/1.1 200 OK\r\n\r\n')
for p in range(0, len(outputdata)):
myCSocks[i].send(outputdata[p])
myCSocks[i].close()
except IOError:
connectionSocket.send('HTTP/1.1 404 Bad Request\r\n\r\n')
connectionSocket.send('<HTML><p>ERROR 404: BAD REQUEST!</p></HTML>')
serverSocket.close()
exit()
Have a look at the built-in socket module here (http://docs.python.org/2/library/socket.html). This allows you to create sockets, and send and receive data, and there are simple examples in the online documentation. Your code will probably work if you replace the strings with actual sockets. If you want to store several sockets by name, you could use a dictionary:
theDict = {}
theDict['socket1'] = socket.socket()
etc.
If CSock1 is a class already defined you can just refer to the class objects. However, if you are trying to do a multi-threaded, there's better ways to do that: Multithreaded web server in python. If you are just trying to use sockets, I'd look at Multi Threaded TCP server in Python (the second answer is best).
A very simple echo TCP (SOCK_STREAM) server demonstrating how to implement a multiprocessing server. Makes use of threadPoolExecutor to
accept connections asynchronously.
Server:
import socket
import concurrent.futures
def server_instance(addr):
HOST = addr[0]
PORT = addr[1]
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print(f"Linked with: {addr}")
while True:
data = conn.recv(1024)
if not data:
break
conn.sendall(data)
return f'DONE'
addresses = [
('127.0.0.1', 65432),
('127.0.0.1', 65431),
('127.0.0.1', 65433),
('127.0.0.1', 65435),
('127.0.0.1', 65434),
]
with concurrent.futures.ThreadPoolExecutor() as executor:
for address, status in zip(addresses, executor.map(server_instance, addresses)):
print(f"{address}: {status}")
A client to send data to server.
Client:
import socket
import sys
HOST = '127.0.0.1'
if len(sys.argv) != 3:
print(f"[*] Usage: python {sys.argv[0]} <PORT> <MESSAGE>")
sys.exit()
PORT = int(sys.argv[1])
print(f"PORT SET TO: {PORT}")
MSG = bytes(sys.argv[2], encoding='utf8')
print(f"MESSAGE SET TO: {MSG}")
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
s.sendall(MSG)
data = s.recv(1024)
print(f'[r] {repr(data)}')
f-strings require python3.6 and up
concurrent futures require python 3.2 and up