I would like to extract date time from PCAP files only for ARP packets and would like to save as csv/txt. i did uses below code for extract time. print command is working fine with time. but when its save at csv file its only one date and one time (example 14:59:58) save in to csv file. can any one suggest for modify the codes for extract ARP times from pcap and save to csv CORRECTLY. Thank you.
with open("../data/" + filename + ".pcap", 'rb') as f:
pcap = dpkt.pcap.Reader(f)
requests = []
replies = []
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
# If the packet is not arp
if eth.type != 2054:
continue
try:
arp = eth.arp
except Exception as e:
continue
src = dpkt.socket.inet_ntoa(arp.spa)
tgt = dpkt.socket.inet_ntoa(arp.tpa)
if arp.op == 2:
count_duplication(replies, src, tgt)
elif arp.op == 1:
count_duplication(requests, src, tgt)
packet_time = datetime.datetime.utcfromtimestamp(ts).strftime("%m/%d/%Y, %H:%M:%S")
print (packet_time)
save_packets(sorted(requests, key=lambda x: -x[2]), '../tmp/count-requests-xyz' + '.csv', packet_time)
# Save Packets
def save_packets(packets,filename,tcp,ts, degree_sorted):
with open(filename, 'w') as f:
for packet in packets:
data = ''
for item in packet:
data = data + str(item) + ','
f.write(data + tcp + datetime.datetime.utcfromtimestamp(ts).strftime("%m/%d/%Y, %H:%M:%S") + degree_sorted + '\n')
import socket
import datetime
import dpkt
def _inet_to_str(inet):
try:
return socket.inet_ntop(socket.AF_INET, inet)
except ValueError:
return socket.inet_ntop(socket.AF_INET6, inet)
def arp(pcap_path):
def _is_arp(packet):
return True
with open(pcap_path, 'rb') as f:
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
if not isinstance(eth.data, dpkt.ip.IP):
continue
if not _is_arp(eth):
continue
ip = eth.data
# write to file instead of printing
print('{},{},{}'.format(_inet_to_str(ip.src), _inet_to_str(ip.dst),
datetime.datetime.utcfromtimestamp(ts).strftime("%m/%d/%Y, %H:%M:%S")))
Related
I made a file transferrer and the problem is that out of unknown reason it lets me only send one file... When I try the second time the program works fine, but the file doesn't show up in directory. It would mean a lot to me if someone helped me out.
Code for sender:
import os
import shutil
import socket
import time
# Creating a socket.
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind((socket.gethostname(), 22222))
sock.listen(5)
print("Host Name: ", sock.getsockname())
# Accepting the connection.
client, addr = sock.accept()
original = ""
print("When you want to stop with file uploading type -> STOP <-")
while (1):
original = input(str("Filepath:"))
if (original!="STOP"):
filename = os.path.basename(original)
target = r'C:\Users\Gasper\Desktop\transfer\filename'
path = target.replace('filename', filename)
new_file = shutil.copy(original, path)
# Getting file details.
file_name = filename
file_size = os.path.getsize(file_name)
# Sending file_name and detail.
client.send(file_name.encode())
client.send(str(file_size).encode())
# Opening file and sending data.
with open(file_name, "rb") as file:
c = 0
# Running loop while c != file_size.
while c <= file_size:
data = file.read(1024)
if not data:
break
client.sendall(data)
c += len(data)
os.remove(filename)
else:
break
print("File Transfer Complete!")
input("Press enter to exit...")
# Closing the socket.
sock.close()
Code for receiver:
import socket
import time
host = input("Host Name: ")
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Trying to connect to socket.
try:
sock.connect((host, 22222))
print("Connected Successfully")
except:
print("Unable to connect")
exit(0)
# Send file details.
file_name = sock.recv(100).decode()
file_size = sock.recv(100).decode()
# Opening and reading file.
with open("./rec/" + file_name, "wb") as file:
c = 0
# Starting the time capture.
start_time = time.time()
# Running the loop while file is recieved.
while c <= int(file_size):
data = sock.recv(1024)
if not data:
break
file.write(data)
c += len(data)
# Ending the time capture.
end_time = time.time()
print("File transfer Complete!")
input("Press enter to exit...")
# Closing the socket.
sock.close()
Example:
Filepath: C\Users\Admin\Desktop\Directory\File1.txt(I put in the first file path and it transfers successfully)
Filepath: C\Users\Admin\Desktop\Directory\File2.txt(I put in the second file path and it doesnt transfer at all)
Im doing a project where it connect to a server directory and read all their files.
So i just wrote a code to download the server files whenever i click on it. I can read small size file with no issues, but when i want to view a large content, only 1 line can be view and store to a list. Although i cant read all the large content, but im able to download it with no issues.
I can read and download all small size content with no issues:
The large file that i want to read from:
Output that i got when i read the large files. (Cant read all the content but i successfully to download the full content file)
CLIENT CODE:
def mouseHover(event):
x = lbox.curselection()[0]
file = lbox.get(x)
ext = (".txt", ".csv")
if file.endswith(ext):
self.s.send(("fdown~" + file).encode("utf-8")) #must have
data = self.s.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
self.s.send("OK".encode("utf-8"))
f = open(file, 'wb') # must have
data = (self.s.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = self.s.recv(1024)
totalRecv += len(data)
f.write(data)
sys.stdout.write("\r|" + "█" * int((totalRecv / float(filesize)) * 50) + "|{0:.2f}".format(
(totalRecv / float(filesize)) * 100) + "% ")
sys.stdout.flush()
time.sleep(0.01)
print("\nDownload Complete!")
f.close()
global data2
data2= data.splitlines()
print(data2)
self.text.delete('1.0', tk.END)
self.text.insert(tk.END, data)
else:
messagebox.showinfo("WARNING", "Currently only .txt/csv file is supported.")
lbox.bind("<<ListboxSelect>>", mouseHover)
SERVER CODE:
# Create a Socket ( connect two computers)
def create_socket():
try:
global host
global port
global s
host = ""
port = 9999
s = socket.socket()
except socket.error as msg:
create_socket()
# Binding the socket and listening for connections
def bind_socket():
try:
global host
global port
global s
s.bind((host, port))
s.listen(5)
except socket.error as msg:
bind_socket()
# send file list
def flist(conn):
try:
arr = pickle.dumps(os.listdir())
conn.send(arr)
except:
conn.send(('Error').encode("utf-8"))
# accept file from server
def fdown(filename, conn):
try:
data = conn.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = data[6:]
conn.send("OK".encode("utf-8"))
f = open(filename, 'wb')
data = (conn.recv(1024))
totalRecv = len(data)
f.write(data)
while int(totalRecv) < int(filesize):
data = conn.recv(1024)
totalRecv += len(data)
f.write(data)
f.close()
except:
conn.send(('Error').encode("utf-8"))
# send file
def fup(filename, conn):
if os.path.isfile(filename):
conn.send(str.encode("EXISTS " + str(os.path.getsize(filename))))
filesize = int(os.path.getsize(filename))
userResponse = conn.recv(1024).decode("utf-8")
if userResponse[:2] == 'OK':
with open(filename, 'rb') as f:
bytesToSend = f.read(1024)
conn.send(bytesToSend)
totalSend = len(bytesToSend)
while int(totalSend) < int(filesize):
bytesToSend = f.read(1024)
totalSend += len(bytesToSend)
conn.send(bytesToSend)
else:
conn.send("ERROR".encode("utf-8"))
# main
def main(s):
while True:
data = (s.recv(1024)).decode("utf-8").split('~')
if data[0] == 'fdown':
fup(data[1], s)
elif data[0] == 'fup':
fdown(data[1], s)
elif data[0] == 'flist':
flist(s)
break
else:
s.send(".".encode('utf-8'))
# Establish connection with a client (socket must be listening)
def socket_accept():
conn, address = s.accept()
main(conn)
conn.close()
create_socket()
bind_socket()
socket_accept()
After you read each block of data, concatenate it to a string containing the whole file. Then at the end of the loop you can split this into lines and display it in the text box.
There's also no need to limit your recv() calls to 1000 bytes. Use filesize - totalRecv as the limit, and it will receive as much as is available, but not go past the end of the file.
There's no need to convert filesize to int every time through the loop, do it once when you assign the variable.
def mouseHover(event):
x = lbox.curselection()[0]
file = lbox.get(x)
ext = (".txt", ".csv")
if file.endswith(ext):
self.s.send(("fdown~" + file).encode("utf-8")) #must have
data = self.s.recv(1024).decode("utf-8")
if data[:6] == 'EXISTS':
filesize = int(data[6:])
self.s.send("OK".encode("utf-8"))
all_data = ''
with open(file, 'wb') as f: # must have
totalRecv = 0
while totalRecv < filesize:
data = self.s.recv(filesize - totalRecv)
totalRecv += len(data)
all_data += data
f.write(data)
sys.stdout.write("\r|" + "█" * int((totalRecv / filesize) * 50) + "|{0:.2f}".format(
(totalRecv / filesize) * 100) + "% ")
sys.stdout.flush()
time.sleep(0.01)
print("\nDownload Complete!")
global data2
data2= all_data.splitlines()
print(data2)
self.text.delete('1.0', tk.END)
self.text.insert(tk.END, all_data)
else:
messagebox.showinfo("WARNING", "Currently only .txt/csv file is supported.")
lbox.bind("<<ListboxSelect>>", mouseHover)
I have this simple python server-client file transfer project going on.
There are two parts to each side. First, the client sends a file to server for the first part. Server then appends a line and sends back the file to client in the second part.
My issue is that for some reason, the server code is stuck on receiving whenever I have the return file code in it. If I should comment out the second section of the code, the server receives all the file sent by client. Otherwise it freezes on receiving. And yes, client did send it.
You can ignore all the print commands, just there to see where the problem is.
servercode:
import socket
ssFT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ssFT.bind((socket.gethostname(), 8756))
ssFT.listen(1)
while True:
(conn, address) = ssFT.accept()
text_file = 'fileProj.txt'
#Receive, output and save file
with open(text_file, "wb") as fw:
print("Receiving..")
while True:
print('receiving')
data = conn.recv(1024)
print('Received: ', data.decode('utf-8'))
if not data:
print('Breaking from file write')
break
fw.write(data)
print('Wrote to file', data.decode('utf-8'))
fw.close()
print("Received..")
#Append and send file
print('Opening file ', text_file)
with open(text_file, 'ab+') as fa:
print('Opened file')
print("Appending string to file.")
string = b"Append this to file."
fa.write(string)
fa.seek(0, 0)
print("Sending file.")
while True:
data = fa.read(1024)
conn.send(data)
if not data:
break
fa.close()
print("Sent file.")
break
ssFT.close()
client code:
import socket
csFT = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
csFT.connect((socket.gethostname(), 8756))
text_file = 'passphrase.txt'
#Send file
with open(text_file, 'rb') as fs:
#Using with, no file close is necessary,
#with automatically handles file close
while True:
data = fs.read(1024)
print('Sending data', data.decode('utf-8'))
csFT.send(data)
print('Sent data', data.decode('utf-8'))
if not data:
print('Breaking from sending data')
break
fs.close()
#Receive file
print("Receiving..")
with open(text_file, 'wb') as fw:
while True:
data = csFT.recv(1024)
if not data:
break
fw.write(data)
fw.close()
print("Received..")
csFT.close()
I tested your code locally with Python 3.
The problem that I saw was with conn.recv in the server code. Because of the conn.recv blocks the connection and it is waiting for more data.
The solution that I found was sending commands to server informing about BEGIN and END of the data transfer, like that:
client.py
#Send file
with open(text_file, 'rb') as fs:
#Using with, no file close is necessary,
#with automatically handles file close
csFT.send(b'BEGIN')
while True:
data = fs.read(1024)
print('Sending data', data.decode('utf-8'))
csFT.send(data)
print('Sent data', data.decode('utf-8'))
if not data:
print('Breaking from sending data')
break
csFT.send(b'ENDED') # I used the same size of the BEGIN token
fs.close()
server.py
with open(text_file, "wb") as fw:
print("Receiving..")
while True:
print('receiving')
data = conn.recv(32)
if data == b'BEGIN':
continue
elif data == b'ENDED':
print('Breaking from file write')
break
else:
print('Received: ', data.decode('utf-8'))
fw.write(data)
print('Wrote to file', data.decode('utf-8'))
fw.close()
print("Received..")
Client.py complete code:
https://pastebin.com/LySsgEe4
Server.py complete code:
https://pastebin.com/KADZpqkM
I hope to help!
The way I solved this same issue is by sending the file size first, then the server can stop waiting as soon as it receives the whole file. I dunno whether there is a better solution or not but this works like a charm:
BUFFER_SIZE = 1024
client.py
import os
fsize = os.path.getsize(text_file)
csFT.send(str(fsize).encode('utf-8'))
with open(text_file, 'rb') as fs:
data = fs.read(BUFFER_SIZE)
while data:
csFT.send(data)
data = fs.read(BUFFER_SIZE)
server.py
with open(text_file, 'wb') as fw:
msg = ssFT.recv(BUFFER_SIZE)
fsize = int(msg.decode('utf-8'))
rsize = 0
while True:
data = ssFT.recv(BUFFER_SIZE)
rsize = rsize + len(data)
fw.write(data)
if rsize >= fsize:
print('Breaking from file write')
break
I want to print out the packet data from a pcap file. The code below stores the packet data in an array but I can't figure out how to print each element of the array and then split up the data from there. A for loop on the array just returns an error.
import dpkt
import socket
f = open('test.pcap', 'r')
pcap = dpkt.pcap.Reader(f)
info = []
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
if not hasattr(eth, 'ip'):
continue
info.append(eth.ip)
f.close()
print info
It is not clear what exactly you want to print. It depends on what you are looking for.
If you want to print the tcp data, then here is how you do it:
import dpkt
f = open('test.pcap')
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
tcp = ip.data
If you want to print data in a higher layer, you can extend the above example to do so. HTTP, for example, is as follows:
import dpkt
f = open('test.pcap')
pcap = dpkt.pcap.Reader(f)
for ts, buf in pcap:
eth = dpkt.ethernet.Ethernet(buf)
ip = eth.data
tcp = ip.data
if tcp.dport == 80:
http = dpkt.http.Request(tcp.data)
print http.data
For more details, see the example here, or the examples in the dpkt project.
I'm using python version 2.7.9 and i try to send png file.
But something strange happens..i using sockets and sends a post request(or kind of).
I send the request to the server from the client,then i prints the length of the request received on the server, for example, the length is:1051.
Then I do a regex to take the png file data, and then prints the length, and the length is 2632, that he larger than the response?!
I think the problem is that it's actually write the content, but not the right of representation, I tried different things but they did not work, so I ask here how to solve this problem.
Server source code:
import socket
import re
server = socket.socket()
server.bind(('0.0.0.0',8080))
while True:
server.listen(2)
(client, client_addr) = server.accept()
print 'IP :',client_addr
res = client.recv(0xfffffff)
print len(res)
#get file name
file_name = res.split('&')[0]
file_name = str(file_name.split('=')[1])
print repr(res)
#get the data of the file
raw_img = str(re.findall("&photo_data=(.*)" ,res ,re.DOTALL))
print "File name:" + file_name
print "Size:" + str(len(raw_img))
with open(file_name, 'wb') as f:
f.write(raw_img)
print "Done"
Client source code:
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
raw_data = open('test.png', 'rb').read()
save_file_name = raw_input("Enter the file name:")
print len(raw_data)
output = 'POST /upload HTTP/1.1\r\n'
output += 'Content-Length:' + str(len(raw_data)) + str(len(save_file_name)) + '\r\n\r\n'
output += 'file_name=' + save_file_name + '&'
output += 'photo_data=' + raw_data
print len(output)
client.send(output)
client.close()
First, you should use while True to receive the full data:
res = ''
while True:
data = client.recv(1024)
if not data:
break
res += data
print len(res)
Then, re.findall actually returns an array, not a string. So you should do this:
r = re.findall("&photo_data=(.*)" ,res ,re.DOTALL)
raw_img = str(r[0])
Now it works fine.
Why doesn't the code before work? Let's say we have a list:
r = ['\x45']
The data in raw_img part is basically like this. If we brutely convert this list to a str, we have:
print len(str[r])) # ['E'], 5
Actually, what we need is r[0]:
print len(str[r[0])) # 1
That's why the size of the file became larger.