I am going to send DNS queries over UDP to a DNS server using the Python3 programming language. This is a description:
Your program must send requests for either IPv4 ("A) or IPv6 ("AAAA") addresses
Your program must take 3 command-line arguments:
The type of of address requested (denoted with the --type flag), which can have the value 'A' or 'AAAA'
The host name being queried (denoted with the --name flag)
The IP address of the DNS server to query (denoted with the --server flag)
why when I print(raw_bytes2), I received nothing
#!/usr/bin/env python3
# Python DNS query client
#
# Example usage:
# ./dns.py --type=AAAA --name=www.google.com --server=8.8.8.8
# Should provide equivalent results to:
# dig www.google.com AAAA #8.8.8.8 +noedns
# (note that the +noedns option is used to disable the pseduo-OPT
# header that dig adds. Our Python DNS client does not need
# to produce that optional, more modern header)
import argparse
import ctypes
import random
import socket
import struct
import sys
def main():
# Setup configuration
parser = argparse.ArgumentParser(description='DNS client for ECPE 170')
parser.add_argument('--type', action='store', dest='qtype',
required=True, help='Query Type (A or AAAA)')
parser.add_argument('--name', action='store', dest='qname',
required=True, help='Query Name')
parser.add_argument('--server', action='store', dest='server_ip',
required=True, help='DNS Server IP')
args = parser.parse_args()
qtype = args.qtype
qname = args.qname
server_ip = args.server_ip
port = 53
server_address = (server_ip, port)
if qtype not in ("A", "AAAA"):
print("Error: Query Type must be 'A' (IPv4) or 'AAAA' (IPv6)")
sys.exit()
# Create UDP socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((server_ip, port))
# Generate DNS request message
# type
raw_bytes = bytearray()
if qtype == "A":
raw_bytes.append(0x00)
raw_bytes.append(0x01)
elif qtype == "AAAA":
raw_bytes.append(0x00)
raw_bytes.append(0x1c)
#qname
split = qname.split(".")
string = ""
for i in split:
hexs = hex(len(i))
string += str(hexs)+i
#string += "0x00"
raw_bytes +=bytes(string,'ascii')
#sever 8.8.8.8
raw_bytes.append(0x08)
raw_bytes.append(0x08)
raw_bytes.append(0x08)
raw_bytes.append(0x08)
# Send request message to server
# print(raw_bytes)
bytes_send = s.sendto(raw_bytes,server_address)
# Receive message from server
max_bytes = 4096
(raw_bytes2,src_addr) = s.recvfrom(max_bytes)
print(raw_bytes2)
# Close socket
# ---------
s.close()
# Decode DNS message and display to screen
print(bytes_send)
# dns.decode_dns(raw_bytes)
if __name__ == "__main__":
sys.exit(main())
Related
I got 50% of this to work - pi #1 acts as the server and sends messages to the client (pi #2).
But how can it RECEIVE information back from the client?
Basically, the issue I'm having is that pi #1 needs to receive commands from pi #2 as well.
SERVER.py
import socket
import time
print("This is pizero2 as server.")
# REMOTE SETUP as SERVER
addresses = {
'littlechefee': {'ip': '192.168.39.242','port': 5003}, # pi4-one pi4 L wall .. liqs
}
sockets = []
i = 0
for addr in addresses:
ip = addresses[addr]['ip']
port = addresses[addr]['port']
sockets.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
sockets[i].setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
try:
sockets[i].connect((ip,port))
print(f'Success, connected with {addr}. ')
except:
print("Unable to Connect Rpi with IP: {} and Port: {}".format(ip,port ))
i += 1
def send():
command = 'test from pizero2'
indx = 0 # bc only 1 remote pi
print(f"Sending littlechefee a cmd.")
try:
sockets[indx].sendall(str(command).encode('utf-8'))
except:
print('Unable to send command! Invalid options')
while True:
send()
CLIENT.py
import socket
import time
# REMOTE SETUP as CLIENT
rcv_ip = '192.168.39.46' # Please insert the receiver own ip (ip of rpi on which this script is running.) Example : '192.268.xx.xx'
rcv_port = 5002 # please use 5001 upto 5006 for different rpi's
sock_rcv = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock_rcv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock_rcv.bind((rcv_ip,rcv_port))
sock_rcv.listen(10)
def get_data():
dt_r, adr_r = sock_rcv.accept()
while True:
cmd = dt_r.recv(1024)
if cmd:
cmd = cmd.decode('utf-8') # str = ['dispense', [13, 6, 13], 50]
cmd = cmd.split(' ') # lst = ["['dispense',", '[13,', '6,', '13],', '50]']
print("cmd is: ", cmd) # cmd = ["['nema',", "'W',", "'5',", '3000]']
else:
print("Connection closed.")
break
time.sleep(1)
while True:
get_data()
I am trying to transfer multiple images over the persistent TCP connection in python. According to my knowledge, this code should work fine but sometimes it shows the following error ValueError: invalid literal for int() with base 10: '6789:'
For each image, I am first trying to send the size of that image to the client.
Can someone please help me with what I am doing wrong or otherwise guide how to do this in other ways
Server code
import socket
import time
import os
port = 6004
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host = socket.gethostname() # Get local machine name
s.bind((host, port)) # Bind to the port
s.listen(5) # Now wait for client connection.
print ('Server listening....')
conn, addr = s.accept()
print ('Got connection from', addr)
# data = conn.recv(1024)
# print('Server received', repr(data))
start =time.time()
for i in range(2):
filename="sc" + str(i) + ".jpg"
size = str(os.path.getsize(filename))
try:
conn.send(size.encode())
except:
print('ckckckckckck')
print('filesize', size, len(size))
f = open(filename,'rb')
current=0
size = int(size)
while current <size:
l = f.read(1024)
conn.send(l)
current+=len(l)
print('current',current)
print('l',len(l))
if(current==size):
break
print('close current',current)
f.close()
print('Done sending')
conn.send(b'Thank you for connecting')
#conn.close()
print(time.time()-start)
Client code
import os
import socket
import time # Import socket module
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostname() # Get local machine name
port = 6004 # Reserve a port for your service.
s.connect((host, port))
s.send(b'Hello server!')
for i in range(2):
data = None
data = s.recv(1024)
data = data.decode()
size = int(data)
print(size)
filename = "sc" + str(i) + ".jpg"
f = open(filename,'wb')
current =0
while current<size:
data = s.recv(1024)
f.write(data)
current+=len(data)
# print('data',len(data))
# print('current',current)
if(current==size):
break
print('close current',current)
f.close()
print('Successfully get the file')
s.close()
print('connection closed')
data = s.recv(5)
You expect that the size is within the first 5 bytes and you expect to get it with one recv. But, the actual size can be less than 5 bytes or more since you don't enforce a specific number of bytes when sending:
conn.send(size.encode())
Thus what could happen here is that the size you read in the client is either too small (if the original size was larger) or that the size used less than 5 bytes and there are already data from the file contents within the 5 bytes you read. And this causes the error you see.
Note that TCP is a byte-stream protocol and not a message protocol, which means that what you send is not necessarily what you recv. Instead the data from multiple send could be read within one recv or a single send could make multiple recv necessary. Thus a better design of your code would make sure that it always writes a fixed length for the length and always makes sure that it got the full length before trying to interpret the data as length.
I'm new to python, to be honest I was never into coding but It has come to it where I need to write some scripts, following is my script, I did pick some from here and there and finally made it to work, should I be using class and functions with this current code to make it look more professional and optimal? can someone help me to identify what is done wrong here?
import csv,subprocess,paramiko,time,socket
from datetime import date
IP = {}
Type = {}
Host = {}
Username = {}
Password = {}
hostname = {}
status = {}
with open('Output.csv', 'r', newline='') as csvinput:
reader = csv.DictReader(csvinput)
for item in reader:
IP = item['IP']
Host = item['Hostname']
Username = item['Username']
Password = item['Password']
Type = item['Type']
date = date.today()
if 'Ping' in Type:
print('This is ping device')
try:
ip = socket.gethostbyname(IP)
except socket.error:
pass
name = socket.getfqdn(IP)
data = name
hostname = item['IP']
response = subprocess.Popen(['ping.exe',hostname], stdout = subprocess.PIPE).communicate()[0]
response = response.decode()
print(response)
if 'bytes=32' in response:
status = 'Up'
elif 'destination host unreachable' in response:
status = 'Unreachable'
else:
status = 'Down'
if status == 'Down':
ip = 'Not Found'
with open('Ping-%s.txt' % (date), 'a', newline='') as f:
f = csv.writer(f)
f.writerow([hostname] + [data] + [status] + [ip])
## with open('Ping-%s.csv' % (date), 'a', newline='') as csvoutput:
## output = csv.writer(csvoutput)
## output.writerow([hostname] + [data] + [status] + [ip])
elif 'COR' in Type:
# Create instance of SSHClient object
remote_conn_pre = paramiko.SSHClient()
# Add untrusted hosts
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Initiate SSH connection
remote_conn_pre.connect(IP, username=Username, password=Password, port=22)
print("SSH connection established to %s" % IP)
# Use invoke_shell to establish an 'interactive session'
remote_conn = remote_conn_pre.invoke_shell()
print("Interactive SSH session established")
# Strip the initial router prompt
terminal_output = remote_conn.recv(1000)
# Send the router a command
remote_conn.send("\n")
remote_conn.send("terminal length 0\n")
time.sleep(1)
remote_conn.send("sh run\n")
time.sleep(5)
terminal_output = remote_conn.recv(9999999)
print(terminal_output.decode())
output1 = open('%s-%s.txt' % (Host,date), 'w')
output1.write(terminal_output.decode())
output1.close()
remote_conn_pre.close()
elif 'AP' in Type:
# Create instance of SSHClient object
remote_conn_pre = paramiko.SSHClient()
# Add untrusted hosts
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Initiate SSH connection
remote_conn_pre.connect(IP, username=Username, password=Password, port=22)
print("SSH connection established to %s" % IP)
# Use invoke_shell to establish an 'interactive session'
remote_conn = remote_conn_pre.invoke_shell()
print("Interactive SSH session established")
# Strip the initial router prompt
terminal_output = remote_conn.recv(1000)
# Send the router a command
remote_conn.send("\n")
remote_conn.send("sh run\n")
time.sleep(10)
terminal_output = remote_conn.recv(9999999)
print(terminal_output.decode())
output1 = open('%s-%s.txt' % (Host,date), 'w')
output1.write(terminal_output.decode())
output1.close()
remote_conn_pre.close()
elif 'EFW' in Type:
# Create instance of SSHClient object
remote_conn_pre = paramiko.SSHClient()
# Add untrusted hosts
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Initiate SSH connection
remote_conn_pre.connect(IP, username=Username, password=Password, port=22)
print("SSH connection established to %s" % IP)
# Use invoke_shell to establish an 'interactive session'
remote_conn = remote_conn_pre.invoke_shell()
print("Interactive SSH session established")
# Strip the initial router prompt
terminal_output = remote_conn.recv(1000)
# Send the router a command
remote_conn.send("\n")
remote_conn.send("show full-configuration\n")
time.sleep(10)
terminal_output = remote_conn.recv(9999999)
print(terminal_output.decode())
output1 = open('%s-%s.txt' % (Host,date), 'w')
output1.write(terminal_output.decode())
output1.close()
remote_conn_pre.close()
elif 'LUS' in Type:
# Create instance of SSHClient object
remote_conn_pre = paramiko.SSHClient()
# Add untrusted hosts
remote_conn_pre.set_missing_host_key_policy(paramiko.AutoAddPolicy())
# Initiate SSH connection
remote_conn_pre.connect(IP, username=Username, password=Password, port=22)
print("SSH connection established to %s" % IP)
# Use invoke_shell to establish an 'interactive session'
remote_conn = remote_conn_pre.invoke_shell()
print("Interactive SSH session established")
# Strip the initial router prompt
terminal_output = remote_conn.recv(1000)
# Send the router a command
remote_conn.send("\n")
remote_conn.send("terminal datadump\n")
time.sleep(1)
remote_conn.send("sh run\n")
time.sleep(10)
terminal_output = remote_conn.recv(9999999)
print(terminal_output.decode())
output1 = open('%s-%s.txt' % (Host,date), 'w')
output1.write(terminal_output.decode())
output1.close()
remote_conn_pre.close()
Python users usually use a code writing style known as PEP-8 (https://www.python.org/dev/peps/pep-0008/)
There were some multiple things incorrect/out-of-place :
1. Don't import multiple packages in one line. (If they're not from same parent class)
import csv,subprocess,paramiko,time,socket
to :
import csv
import subprocess
import paramiko
import time
import socket
from datetime import date
2. Use space seperation after comma
['ping.exe',hostname]
to :
['ping.exe', hostname]
3. A empty line at the end of file.
And it does look good to add classes and functions but the most important reason to make a class is its reproducibility.
It all just matters how many times do you use this snippet.
There are many resources from where you can learn how to make a class and its functions
https://www.programiz.com/python-programming/class
Happy Coding. :)
I have a server.py and client.py pair. When I run the server on my machine and open multiple terminals to runs clients, I can connect fine. But when I try to run clients on another computer, the client never connects to the server. I'm pretty sure I tested this code a few months ago on multiple computers and it worked fine (though maybe I'm remembering wrong), but I think I updated my python version, so maybe that's why? How can I change my code below so it works?
server.py
import socket
from threading import Thread
import sys
clients = []
def recv(clientsocket):
while True:
msg = clientsocket.recv(1024) # wait for message from any of the clients.
print("\n" + msg.decode())
for c in clients: # send to all the clients.
c.send(msg)
def send(clientsocket):
while True:
msg = "[Server] %s" % input("\n") # wait for input
print(msg)
for c in clients: # send to all the clients.
c.send(msg.encode())
clientsocket.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostname() # Get local machine name
#port = 3001 # Reserve a port for your service.
port = int(input("Enter port: "))
print ('Server started at [%s]' % socket.gethostbyname(host))
print ('Waiting for clients...')
#s.bind((host, port)) # Bind to the port
s.bind((socket.gethostbyname(host), port))
s.listen(5) # Now wait for client connection.
while True:
#Waits until someone new to accept
c, addr = s.accept()
print(addr, "connected.")
clients.append(c)
thread_recv = Thread(target=recv, args=((c,)))
thread_recv.start()
thread_send = Thread(target=send, args=((c,)))
thread_send.start()
s.close()
client.py
import socket
from threading import Thread
hostname = input("Enter hostname/IP to connect to: ")
# port = 3001
port = int(input("Enter port: "))
clientsocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
clientsocket.connect((hostname, port))
def recv():
while True:
print("\n" + clientsocket.recv(2048).decode())
def send(username):
while True:
msg = "[%s] %s" % (username, input(""))
clientsocket.send(msg.encode()) # send message to the server.
username = input("Choose a username: ")
msg = "[%s has just connected]" % (username)
clientsocket.send(msg.encode())
thread_send = Thread(target=send, args=(username,))
thread_send.start()
thread_recv = Thread(target=recv, args=())
thread_recv.start()
while True:
# keep the threads going.
pass
Edit
Every time I start the server, it says my ip address is the same: 192.168.56.1. Even though I've turned my computer off and tried again. But when I go to Google and ask what is my ip address, it is something totally different. Why does the socket keep choosing 192.168.56.1? Is there something special about it? Is this something related to my problem?
Just bind you server to 0.0.0.0 and bind it to all network interfaces:
server.py
s.bind(('0.0.0.0', port))
Then the code in server.py will end up being something like this:
import socket
from threading import Thread
import sys
clients = []
def recv(clientsocket):
while True:
msg = clientsocket.recv(1024) # wait for message from any of the clients.
print("\n" + msg.decode())
for c in clients: # send to all the clients.
c.send(msg)
def send(clientsocket):
while True:
msg = "[Server] %s" % input("\n") # wait for input
print(msg)
for c in clients: # send to all the clients.
c.send(msg.encode())
clientsocket.close()
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # Create a socket object
host = socket.gethostname() # Get local machine name
#port = 3001 # Reserve a port for your service.
port = int(input("Enter port: "))
print ('Server started at [%s]' % socket.gethostbyname(host))
print ('Waiting for clients...')
#s.bind((host, port)) # Bind to the port
s.bind(('0.0.0.0', port))
s.listen(5) # Now wait for client connection.
while True:
#Waits until someone new to accept
c, addr = s.accept()
print(addr, "connected.")
clients.append(c)
thread_recv = Thread(target=recv, args=((c,)))
thread_recv.start()
thread_send = Thread(target=send, args=((c,)))
thread_send.start()
s.close()
i need to send a packet using scapy to a dns server i made, and for some reason the server doesnt get the packet
this is the dns server
-- coding: utf-8 --
from scapy.all import *
def le_check(p):
return (DNS in p and p[0][DNSQR].qtype == 1 and p[0][UDP].dport==53)
def main():
data_base = {'www.google.com': ('172.217.23.164','173.194.79.104','173.194.79.99')}
p1=sniff(count=1, lfilter=le_check)
x=p1[0][DNSQR].qname
if x in data_base:
list=data_base[x]
else:
list= "no such name"
print p1[0][DNSQR].qname
print list
send(IP(dst=p1[0][IP].src)/UDP(sport=53, dport=53)/Raw(list))
if __name__ == '__main__':
main()
code from scapy
sendp(IP(dst=MY_IP)/UDP(sport=24601,dport=53)/DNS(qdcount=1,rd=1)/DNSQR(qname="www.google.com",qtype=1))