DNS server using scapy - python

i wrote a python DNS server using Scapy and i have a problem.
i sniff a DNS packet (by filter to A or PTR types) and than i wanna send a relevant response.
i use two computers and in one of them i use nslookup www.google.com
it shows me "request time out error" - timeout was 2 seconds.
BYW i received this packet and i sent a one!! but the other computer didn't get this on time i guess.
i tried to change the timeout to 20 seconds but it just wait 20 seconds.. and than shows an error..
and my server get the packet after this 20 seconds.
how can i solve this problem and what cause it!!
Thanks from advance :)
here some of my code (in the may relevant parts):
def filter_dns(packet):
return DNS in packet and packet[DNS].opcode == 0 and (packet[DNSQR].qtype == 1 or packet[DNSQR].qtype == 12)
server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
server_socket.bind((MY_IP, PORT))
print "Server started successfully! Waiting for data..."
packets = sniff(count=1, lfilter=filter_dns)
def send_typeA(packet, result):
mypacket = IP(dst=Ip_Client) / DNS() / DNSRR()
mypacket[DNSRR].rrname = packet[DNSQR].qname
mypacket[DNSRR].rdata = result # result is the ip of the domain name
mypacket[DNSRR].ttl = 100
print mypacket.show()
send(mypacket)

Related

tracing your python packets over the network

Well, it's nothing much to present but, I wanted to make my cellphone and PC somehow connected, and at very first steps of research, I made these VERY SIMPLE tests:
#this is for the udp client file
import socket as soc
import os
server = "192.167.1.4"
serverPort = 12000
value = 0
sockobj = soc.socket(soc.AF_INET, soc.SOCK_DGRAM)
while True:
message = 'This is my secret message: '
message += input("Enter your message: ")
data = message.encode(encoding="UTF-8")
sockobj.sendto(data, (server, serverPort))
if not value:
# os.system("traceroute 192.168.1.4")
value += 1
import time
time.sleep(5)
print("sleep ended")
message, address = sockobj.recvfrom(2048)
print("I got", message.decode())
sockobj.close()
__
and this is for the udp server file
import socket as soc
import time
server = ''
serverPort = 12000
sockobj = soc.socket(soc.AF_INET, soc.SOCK_DGRAM)
sockobj.bind((server, serverPort))
while True:
message, clientaddress = sockobj.recvfrom(2048)
print("I got the client's address as: ", clientaddress)
print("I got the message")
print("...modifying, this might take time")
message = message.decode().upper()
data = ("Server: {} data with {} length".format(message, len(message.split()))).encode(encoding="UTF-8")
time.sleep(1.5)
sockobj.sendto(data,clientaddress)
print("SENT!")
sockobj.close()
I currently have QPython installed on my android device and am running the server file from there. And the devices do connect and communicate!!
So, at this point, I wanted to see how the packets travelled from my PC to cell phone, running traceroute from terminal was no use, connection was refused to my cell phone's local IP: 192.167.1.4, I thought so I'd do a system call from the udp client script, but no luck from there either. I guess is that the packets would bounce from my PC to router to my cell phone, but, that's just a guess. So, How can I trace my packets for this script?
Probably better served as a comment. But seeing as their has been almost no activity on this post, I figured to just post it as an answer.
Have you tried using: https://github.com/CiscoDevNet/dnac-python-path-trace
It does pretty much what you seem to be looking for. You can look at the code to get an idea of how it works.

Python - Send and Receive of UDP packets

I've started with Python a few month ago. Now I've reached a point where I need some help concerning networking.
I've the following scenario:
One PC and 3 external devices in a small local net.
The PC wants to observe a switch state (on/off) on each device. This will be done by an initial command from the PC to each device.
After receiving this command each device sends automatically a packet with the new state to the PC whenever the switch state has changed.
All the packets on the network are UDP packets
On the PC I have the following Python script running (just for one device):
import socket
UDP_IP1 = "192.168.1.64"
UDP_IP2 = "192.168.1.73"
UDP_IP3 = "192.168.1.74"
UDP_PORT = 45 # used port on external device
port = 52129
message = "Message to observe..." # not the real command string
def SendData():
try:
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.bind(("", port))
msg = message.encode('utf-8')
s.sendto(msg, (UDP_IP1, UDP_PORT))
except:
print("Sending Error!!!\n")
return s
def ReceiveData(sock):
print("Receiving data: \n")
while True:
data, addr = sock.recvfrom(4096) # buffer size is 4096 bytes
print ("received message:", data)
if __name__ == "__main__":
s = SendData()
ReceiveData(s)
My Problem: In principal this script is running, but after approximately 2 minutes without any change of the switch on the device I do not receive any more packets from the external device when the switch state changes. But I can see the incoming packets with the installed Wireshark.
It looks like a time-out when I don't receive anything but 'sock.recvfrom' is still waiting for data.
Is there anyone who has/had the same problem?

PC to raspberry Pi via TCP/IP socket

I am trying to do wireless communications between a PC (macbook) and a Raspberry Pi 2 using python's socket module (python 2.7). The server is the PC and the client is the Pi.
When I run the code (server first then client) both scripts get stuck on the socket.accept() and socket.connect() methods respectfully.
What is funny is that when I do the reverse (Pi being the server and PC being the client) the code works fine, with data been sent correctly.
The scripts below are meant to loop forever whilst incrementing a counter sent over (I increment the port's after each succesful transfer to avoid '[Errno 48] Address already in use' (probably terrible practice I know))
My client script:
import socket
import sys
def read(port):
s = socket.socket()
host = '10.19.92.44' #(IP address of PC (server))
s.connect((host,port))
try:
msg = s.recv(1024)
s.close()
except socket.error, msg:
sys.stderr.write('error %s'%msg[1])
s.close()
print 'close'
sys.exit(2)
return msg
if __name__ == '__main__':
port = 1025
while True:
print 'hey, checking TCP socket'
data = read(port)
print 'i just read %s' % data
print 'port num is: %d' % port
port = port + 1
My server script:
import socket
import time
def send(data, port):
s = socket.socket()
s.bind(('', port))
s.listen(5)
c, addr = s.accept()
print 'Got connection from',addr
c.send(data)
c.close()
if __name__ == '__main__':
port = 1025
num = 1
while True:
print 'hey, sending data'
words = 'helloWorld'
data = words + str(num)
print 'send data: %s' % data
send(data,port)
port = port + 1
num = num + 1
As I mentioned when I swap roles (and replace the server IP address in the client script to the Pis 172.17.33.125) the code works fine...
Any ideas/suggestions?
Thank you very much
I don't have an immediate answer, but I have a couple of ideas.
Your PC and Pi seem to be in different networks. The PC's address is 10.19.92.44, while Pi's is 172.17.33.125. There's a probability that 10.19.92.44 isn't the address you need. In order to find out what is the correct PC IP address to use in the application:
Issue networksetup -listallhardwareports to figure out the name of your wifi interface (should be like en0, en1).
Issue ifconfig, find the wifi interface. The IP address attached to this interface is the one you need.
Another option is to install wireshark on the PC, set up a working system (server-Pi, client-PC) and use wireshark to capture the traffic between the PC and Pi. Wireshark makes it easy to figure out IP addresses of both parties. I would advise to have this program installed whenever you want to debug a complicated networking issue.

How to call a function after some interval in python server?

I've a python socket server which listens to HTTP requests. It returns ip address and it's port after randomly choosing from a list of ip adresses. This result is generated by another file which fetches it from a database. The database is continuously updated. I want the list to be updated after every 10 requests or after 100 seconds any one of them will work. The below code doesn't work for me. The connection gets reset after every five requests. I printed the count and it increased to 10 after every 5 requests. Can anyone tell me what I'm missing here ?
result=get_ip() # Get a list of dictionary by calling get_ip() function
HOST, PORT = '127.0.0.1', 8890
listen_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
listen_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
listen_socket.bind((HOST, PORT))
listen_socket.listen(10)
print 'Serving HTTP on port %s ...' % PORT
count = 0
while True:
if count % 10 == 0:
result=get_ip()
count +=1
client_connection, client_address = listen_socket.accept()
rand_ip = random.choice(result)
ip = rand_ip["ip"]
port = rand_ip["port"]
client_connection.sendall(ip+":"+port)
client_connection.close()
The problem comes from the close. It is dangerous to close a socket immediately after writing something into it. You should first shutdown the socket to make the peer to have a 0 read indicating a proper and of stream
So you script should end with:
client_connection.sendall(ip+":"+port)
try:
client_connection.shutdown(socket.SHUT_WR) # signal end of strem
while True: # wait for the client to close or shutdown his side
q = client_connection.recv(1024)
if len(q) == 0:
break
finally:
client_connection.close() # close the socket only after the client has close its side

sock.recv() is taking too much time to execute in the python code

Following is the code which listens on a port for HTTP requests and sends the request packet to the server running on port 80, gets the response and sends the data back to the client. Now, everything is executing fine but the following line of code :
data = req_soc.recv(1024)
is taking too much time to execute and I have observed that, it takes long time to execute when it is going to/has received the last packet. I have also tried the same code using select.select() but the results are the same. Since I want to handle the data (raw) that is coming from the client and the actual HTTP server, I have no other choice than using sockets.
import socket
import thread
def handle_client(client):
data = client.recv(512)
request = ''
request += data
print data
print '-'*20
spl = data.split("\r\n")
print spl[0]
print spl[1]
if len(request):
req_soc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
req_soc.connect(('localhost', 80))
req_soc.send(request)
response = ''
data = req_soc.recv(1024)
while data:
response += data
print 1
data = req_soc.recv(1024)
req_soc.close()
print response
if len(response):
client.send(response)
client.close()
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(('localhost', 4422))
server.listen(5)
print("Server is running...\n")
MSGLEN = 1024
while 1:
client, address = server.accept()
thread.start_new_thread(handle_client, (client, ))
Clients can do multiple commands (eg: GET) within one connection. You cannot wait for the client to send all the commands because based on what you return it could request more (eg: images of a web page). You have to parse the parts (commands) of request, find the boundary, forward that request to the server and write back the answer to the client. All this in a way that doesn't block on reading the client.
I'm not sure what's the best way to do this in python, but if you spend 5 minutes of googling you'll find a perfect HTTP proxy library.

Categories