Here is what I am trying to do :
I send a DNS request (with dig or whatever), and I intercept it with socket in python. Then, I want to send this same request to the gateway, and wait for the response from the gateway.
import socket
#I redirected all DNS requests from port 53 to port 2525 so I am listening here
port = 2525
ip = '127.0.0.1'
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((ip, port))
#Gateway part
gateway = '192.168.1.1'
port_gateway = 9090
sock_gateway = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_gateway.connect((gateway, port_gateway))
while 1:
data, addr = sock.recvfrom(512)
print(data)
#send the request from User to the gateway :
sock_gateway.sendto(data, (gateway, 53))
reply = sock_gateway.recv(512)
print(reply)
Here is the output : b'7\xa3\x01 \x00\x01\x00\x00\x00\x00\x00\x01\x06google\x03com\x00\x00\x01\x00\x01\x00\x00)\x10\x00\x00\x00\x00\x00\x00\x0c\x00\n\x00\x08\x9b+\xc1\xfa\xf4\xbc\x1c\x14'
This is the data from the DNS request I made, but then, I want to forward it to the gateway, and to listen to the response, but it doesn't get any response.
How can I do that ?
I suggest first use tools that are already built and debugged.
the DNS lookup tool i use is
DNS python
You will have to grab the request scan through the request for the data you need typically the name of server, then start up a new request using the DNS libary.
Trying to just forward a request without altering the raw data typically never works.
import dns.resolver as dns
gateway = '192.168.1.1'
port_gateway = 9090
sock_gateway = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_gateway.connect((gateway, port_gateway))
while 1:
data, addr = sock.recvfrom(512)
## extract the request
request = extract_the_request_data_Fucntion(data)
gateway_reponse = dns.query(request, source=gateway_server_ip, source_port=port_gateway)
## construct responds code goes here
##function to parse the responds and send it back to the client
writing forwarders is not just extracting the data from the UDP packet and forwarding it, it almost always requires additional changes.
Related
I'm trying to do some P2P using UDP. I was able to get my external IP and port, however, when I trigger the other script to use that IP and Port to forward some data, It never reaches the client where I performed the STUN request.
I read about not closing the socket because this could cause the NAT to reallocate that port, but even if I let the socket opened, the socket never receives the data that I try to send from the other client.
I'm using pystun to perform the STUN request.
Here are my snippets:
Client A (The one querying the external IP and port)
import socket
from stun import get_nat_type
# Creating the socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(20)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(("0.0.0.0",15000))
# Querying a STUN server to get IP address and port
nat_type, nat = get_nat_type(s, "0.0.0.0", 15000,
stun_host=None, stun_port=3478)
external_ip = nat['ExternalIP']
external_port = nat['ExternalPort']
# Displaying STUN data and listening for client B to send data
print("Punch hole: ('{0}',{1})".format(external_ip, external_port))
print("listening port for incoming data")
print(s.recvfrom(4096)[0])
Client B (The one sending data via the external IP and port
from socket import *
s = socket(AF_INET, SOCK_DGRAM)
s.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
s.sendto(b"hey!", ('<External IP of Client A>', 11224))
The "Hey" sent by client B is never reaching client A
The pystun that I'm using is that one https://github.com/talkiq/pystun3
I'm trying to make a console chat app in python using socket library.
Whenever I send a message to the server, the server code crashes with the following message:
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Server code
import socket
HOST = socket.gethostbyname(socket.gethostname()) # get the ip address of PC
PORT = 5050
ADDRESS = (HOST, PORT)
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.bind(ADDRESS)
while True:
socket.listen()
conn, addr = socket.accept()
print(f"Connected by {addr}")
while True:
data = conn.recv(64)
print(data.decode('utf-8'))
socket.send(data)
Client code
import socket
HOST = socket.gethostbyname(socket.gethostname()) # get the ip address of PC
PORT = 5050
ADDRESS = (HOST, PORT)
socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket.connect(ADDRESS)
while True:
msg = input("Enter your message")
socket.send(msg.encode('utf-8'))
data = socket.recv(64)
print(data.decode('utf-8'))
What I am trying to achieve is whenever I send a message to the server, the client script should print the sent message. How can I fix that?
You're attempting to send data to your own server socket. You instead want to send to the client that you accepted.
socket.send(data)
Should be:
conn.send(data)
If you think about it, if you had multiple clients, how would you send data to a specific client? By using the socket that accept gave you.
As a side note, you probably don't want to import the module as socket, and also call your variable socket. It's fine here, but if you were to make a more complicated project, you may accidentally refer to the object when you meant to refer to the module. I'd rename the socket object to sock or server_socket to avoid shadowing.
I would like to know if anyone was able to change this code so that instead of it running on a wifi network it ran on http. I did all i could but i do not think there are any tutorials on how to preform this changing.
Server:
import socket
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = ''
port = 1234
server.bind((host, port))
server.listen(5)
run = True
client, addr = server.accept()
print('Got connection from',addr)
while run:
try:
data = input('>>>')
client.send(data.encode('UTF-8'))
msg = client.recv(1024)
print(msg.decode('UTF-8'))
except ConnectionResetError:
print('Client lost server connection')
print('Trying to connect . . .')
client, addr = server.accept()
print('Got connection from',addr)
Client:
import socket
import os
server = socket.socket()
host = '127.0.0.1'
port = 1234
run = True
server.connect((host,port))
while run:
msg = server.recv(1024)
os.popen(msg.decode('UTF-8'))
server.send('Client online . . .'.encode('UTF-8'))
I think you are confused on what TCP and HTTP is. TCP is part of layer 4 of the OSI model. HTTP is layer 7 of the OSI model.
Http is a protocol/standard used to exchange data with another Http enabled endpoint. Http is built on top of TCP. Http uses TCP to send data. The server has a TCP socket listening for data and once it receives data it then passes it along to another "process/program/line of code" to then parse that data using Http standards.
If you are wanting to use http to send/receive data you will need a web framework like Flask, Django or Starlette. They are Http servers with added features to allow you to code what you want to do with the data rather than handling the lower level stuff of parsing the http data being sent over TCP.
Http is a HUGE protocol/standard. If you try to do the parsing from scratch it is a big project to undertake.
I want my visitors to be able to use both HTTP and HTTPS. I am using a simple Python webserver created with socket. I followed this guide: Python Simple SSL Socket Server, but it wasn't that helpful because the server would crash if the certificate cannot be trusted in one of the clients. Here is a few lines of code from my webserver that runs the server:
def start(self):
# create a socket object
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# bind the socket object to the address and port
s.bind((self.host, self.port))
# start listening for connections
s.listen(100)
print("Listening at", s.getsockname())
while True:
# accept any new connection
conn, addr = s.accept()
# read the data sent by the client (1024 bytes)
data = conn.recv(1024).decode()
pieces = data.split("\n")
reqsplit = pieces[0].split(" ");
# send back the data to client
resp = self.handleRequests(pieces[0], pieces);
conn.sendall(resp)
# close the connection
conn.close()
Have another service (something like nginx) handle the https aspect, then configure the service to reverse proxy to your python server
I have a device that sends commands to a webserver. I've redirected those commands to my own server, with the goal of use the device to run another part of my system. In short, the device sends commands, I intercept them and use them.
The commands are sent to my server,but are not valid HTTP requests. I'm trying to use flask to read them with python, because I'd like to have these commands go straight into another web app.
Note that I can't change how the commands are sent.
Using sockets, I can read the data. For instance, here is a version of the data sent via socket (data is meaningless, just for illustration):
b'#123456#A'
In constrast, as HTTP message looks like this:
b'POST / HTTP/1.1\r\nHost: 123.123.123.123:12345\r\nRequest info here'
I know how to filter these (they always start with a #). Can I hook flask to let me handle these request differently, before they are parsed as HTTP requests?
Update: The code I used to read the requests, in case it provides context:
import socket
host = ''
port = 5000
backlog = 5
size = 1024
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host,port))
s.listen(backlog)
while 1:
client, address = s.accept()
data = client.recv(size)
print("Request:")
print(data)
print("\n\n")
if data:
client.send(data)
client.close()