The dns doesnt work if i do this it gives this error and idk whats the matter it just gives me this error:
Traceback (most recent call last):
File "c:\Users\engin\Downloads\All files\dns.py", line 160, in <module>
r = buildresponse(data)
File "c:\Users\engin\Downloads\All files\dns.py", line 155, in buildresponse
dnsbody += rectobytes(domainname, rectype, record["ttl"], record["value"])
TypeError: string indices must be integers
and i did write this code for my DNS Server:
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.bind((ip, port))
def load_zone():
jsonzone = {}
zonefiles = glob.glob('zones/*.zone')
for zone in zonefiles:
with open(zone) as zonedata:
data = json.load(zonedata)
zonename = data["$origin"]
jsonzone[zonename] = data
return jsonzone
zonedata = load_zone()
def getFlags(flags):
byte1 = bytes(flags[:1])
byte2 = bytes(flags[1:2])
rflags = ''
QR = '1'
OPCODE = ''
for bit in range(1,5):
OPCODE += str(ord(byte1) & (1<<bit))
AA = '1'
TC = '0'
RD = '0'
RA = '0'
Z= '000'
RCODE = '0000'
return(int(QR + OPCODE + AA + TC + RD, 2).to_bytes(1, byteorder='big') + int(RA + Z + RCODE, 2).to_bytes(1, byteorder='big'))
def getquestiondomain(data):
state = 0
expectedlenght = 0
domainsting = ''
domainparts = []
x = 0
y = 0
for byte in data:
if state == 1:
if byte != 0:
domainsting += chr(byte)
x += 1
if x == expectedlenght:
domainparts.append(domainsting)
domainsting = ''
state = 0
x = 0
if byte == 0:
domainparts.append(domainsting)
break
else:
state = 1
expectedlenght = byte
# x += 1
y += 1
questiontype = data[y + 1 : y + 3]
return(domainparts, questiontype)
def getzone(domain):
global zonedata
zone_name = '.'.join(domain)
return zonedata[zone_name]
def getrecs(data):
domain, questiontype = getquestiondomain(data)
qt = ''
if questiontype == b'\x00\x01':
qt = 'a'
zone = getzone(domain)
return (zone, qt, domain)
def rectobytes(domainname, rectype, recttl, recval):
rbytes = b'\xc0\x0c'
if rectype == 'a':
rbytes = rbytes + bytes([0]) + bytes([1])
rbytes = rbytes + bytes([0]) + bytes([1])
rbytes += int(recttl).to_bytes(4, byteorder='big')
if rectype == 'a':
rbytes = rbytes + bytes([0]) + bytes([4])
for part in recval.split('.'):
rbytes += bytes([int(part)])
return rbytes
def buildquestion(domainname, rectype):
qbytes = b''
for part in domainname:
lenght = len (part)
qbytes += bytes([lenght])
for char in part:
qbytes += ord(char).to_bytes(1, byteorder='big')
if rectype == 'a':
qbytes += (1).to_bytes(2, byteorder='big')
qbytes += (1).to_bytes(2, byteorder='big')
return qbytes
def buildresponse(data):
TransactionID = data[:2]
# TID = ''
# for byte in TransactionID:
# TID += hex(byte)
Flags = getFlags(data[2:4])
QDCOUNT = b'\x00\x01'
# getquestiondomain(data[12:])
ANCOUNT = len(getrecs(data[12:])[0]).to_bytes(2, byteorder='big')
NSCOUNT = (0).to_bytes(2, byteorder='big')
ARCOUNT = (0).to_bytes(2, byteorder='big')
dnsheader = TransactionID + Flags + QDCOUNT + ANCOUNT + NSCOUNT + ARCOUNT
dnsbody = b''
records, rectype, domainname = getrecs(data[12:])
dnsquestion = buildquestion(domainname, rectype)
for record in records:
dnsbody += rectobytes(domainname, rectype, record["ttl"], record["value"])
return dnsheader + dnsquestion + dnsbody
while 1:
data, addr = sock.recvfrom(512)
r = buildresponse(data)
sock.sendto(r, addr)
and this value record in the for at the very bottom of buildresponse it just prints out #origin
Idk whats the problem or so and then i created this Post and pls help.
pls help!
Okay so now you've shown that your records value is the following dictionary:
records = {'$origin': 'status.minecraft.de.', '$ttl': 3600, 'soa': {'mname': 'ns1.status.minecraft.de.', 'rname': 'admin.status.minecraft.de.', 'serial': '{time}', 'refresh': 3600, 'retry': 600, 'expire': 604800, 'minimum': 86400}, 'ns': [{'host': 'ns1.status.minecraft.de.'}, {'host': 'ns2.status.minecraft.de.'}], 'a': [{'name': '#', 'ttl': 400, 'value': '255.255.255.255'}, {'name': '#', 'ttl': 400, 'value': '127.0.0.1'}, {'name': '#', 'ttl': 400, 'value': '127.0.0.1'}]}
This means that if you were to loop through it how you currently do - for record in records - we know that, since it's a dictionary, each record will be a key of that dictionary (as per this). So, the following code:
for record in records:
print(record)
print(type(record))
Gives the following outpupt - which is just all the keys in the dictionary:
$origin
<class 'str'>
$ttl
<class 'str'>
soa
<class 'str'>
ns
<class 'str'>
a
<class 'str'>
So, that means that if you try to access record["ttl"] or record["value"], since record is a string, this will be like trying to do something like "$ttl"["ttl"], which would give the error string indices must be integers.
However, the issue wouldn't be solved just be replacing record with records, since the records object has no "value" or "ttl" key. It appears that you're actually trying to loop through each value in the "a" key in your records dictionary, since its value is an array of dictionaries that have both a "ttl" and "value" key:
[{'name': '#', 'ttl': 400, 'value': '255.255.255.255'}, {'name': '#', 'ttl': 400, 'value': '127.0.0.1'}, {'name': '#', 'ttl': 400, 'value': '127.0.0.1'}]
Therefore, your fix would simply be:
for record in records["a"]:
dnsbody += rectobytes(domainname, rectype, record["ttl"], record["value"])
Related
I am extracting from the log file and print using the below code
for line in data:
g = re.findall(r'([\d.]+).*?(GET|POST|PUT|DELETE)', line)
print (g)
[('1.1.1.1', 'PUT')]
[('2.2.2.2', 'GET')]
[('1.1.1.1', 'PUT')]
[('2.2.2.2', 'POST')]
How to add to the output
output
1.1.1.1: PUT = 2
2.2.2.2: GET = 1,POST=1
You could use a dictionary to count:
# initialize the count dict
count_dict= dict()
for line in data:
g = re.findall(r'([\d.]+).*?(GET|POST|PUT|DELETE)', line)
for tup in g:
# get the counts for tuple tup if we don't have it yet
# use 0 (second argument to .get)
num= count_dict.get(tup, 0)
# increase the count and write it back
count_dict[tup]= num+1
# now iterate over the key (tuple) - value (counts)-pairs
# and print the result
for tup, count in count_dict.items():
print(tup, count)
Ok, I have to admit this doesn't give the exact output, you want, but from this you can do in a similar manner:
out_dict= dict()
for (comma_string, request_type), count in count_dict.items():
out_str= out_dict.get(comma_string, '')
sep='' if out_str == '' else ', '
out_str= f'{out_str}{sep}{request_type} = {count}'
out_dict[comma_string]= out_str
for tup, out_str in out_dict.items():
print(tup, out_str)
From your data that outputs:
1.1.1.1 PUT = 2
2.2.2.2 GET = 1, POST = 1
I would look towards Counter.
from collections import Counter
results = []
for line in data:
g = re.findall(r'([\d.]+).*?(GET|POST|PUT|DELETE)', line)
results.append(g[0])
ip_list = set(result[0] for result in results)
for ip in ip_list:
print(ip, Counter(result[1] for result in results if result[0] == ip ))
You can use collection.defaultdict
Ex:
from collections import defaultdict
result = defaultdict(list)
for line in data:
for ip, method in re.findall(r'([\d.]+).*?(GET|POST|PUT|DELETE)', line):
result[ip].append(method)
for k, v in result.items():
temp = ""
for i in set(v):
temp += " {} = {}".format(i, v.count(i))
print("{}{}".format(k, temp))
from collections import Counter
x = [[('1.1.1.1', 'PUT')],[('2.2.2.2', 'GET')],[('1.1.1.1', 'PUT')],[('2.2.2.2', 'POST')]]
# step 1: convert x into a dict.
m = {}
for i in x:
a, b = i[0]
if a not in m.keys():
m[a] = [b]
else:
x = m[a]
x.append(b)
m[a] = x
print('new dict is {}'.format(m))
# step 2 count frequency
m_values = list(m.values())
yy = []
for i in m_values:
x = []
k = list(Counter(i).keys())
v = list(Counter(i).values())
for i in range(len(k)):
x.append(k[i] + '=' + str(v[i]))
yy.append(x)
# step 3, update the value of the dict
m_keys = list(m.keys())
n = len(m_keys)
for i in range(n):
m[m_keys[i]] = yy[i]
print("final dict is{}".format(m))
Output is
new dict is {'1.1.1.1': ['PUT', 'PUT'], '2.2.2.2': ['GET', 'POST']}
final dict is{'1.1.1.1': ['PUT=2'], '2.2.2.2': ['GET=1', 'POST=1']}
Without dependencies and using a dict for counting, in a very basic way. Given the data_set:
data_set = [[('1.1.1.1', 'PUT')],
[('2.2.2.2', 'GET')],
[('2.2.2.2', 'POST')],
[('1.1.1.1', 'PUT')]]
Initialize the variables (manually, just few verbs) then iterate over the data:
counter = {'PUT': 0, 'GET': 0, 'POST': 0, 'DELETE': 0}
res = {}
for data in data_set:
ip, verb = data[0]
if not ip in res:
res[ip] = counter
else:
res[ip][verb] += 1
print(res)
#=> {'1.1.1.1': {'PUT': 1, 'GET': 0, 'POST': 1, 'DELETE': 0}, '2.2.2.2': {'PUT': 1, 'GET': 0, 'POST': 1, 'DELETE': 0}}
It's required to format the output to better fits your needs.
I have a below string multiple lines. For each line, I want to split string and add this to a JSON output file. I had done this using string.gettext().split and a regular expression. However I am not sure this is the best way to do it.
Input file :
Server:prod01
Available memory: 20480 Disk:200 CPU:4
Used memory:12438 Disk:120 CPU:3
Unused memory:8042 Disk:80 CPU:1
Server:prod02
Available memory: 40960 Disk:500 CPU:8
Used memory:20888 Disk:320 CPU:3
Unused memory:20072 Disk:180 CPU:5
Expected output JSON:
{"prod01_available_memory":20480}
{"prod01_used_memory":12438}
{"prod01_unused_memory":8042}
{"prod01_available_disk":200}
{"prod01_used_disk":120}
{"prod01_unused_disk":80}
{"prod01_available_cpu":4}
{"prod01_used_cpu":3}
{"prod01_unused_cpu":1}
{"prod02_available_memory":40960}
{"prod02_used_memory":20888}
{"prod02_unused_memory":20072"}
{"prod02_available_disk":500"}
{"prod02_used_disk":380}
{"prod02_unused_disk":120}
{"prod02_available_cpu":8}
{"prod02_used_cpu":3}
{"prod02_unused_cpu":5}
Thanks,
Rinku
Below is my code -
def tsplit(string, *delimiters):
pattern = '|'.join(map(re.escape, delimiters))
return re.split(pattern, string)
prelist = pre.get_text().splitlines()
server_name = re.split('server|:',prelist[0])[2].strip()
if server_name == 'prod01':
#print prelist[1]
prod01_memory_actv = int(re.split('Activated memory|:|Disk|:|CPU|:',prelist[1])[2])
prod01_Disk_actv = int(re.split('Activated memory|:|Disk|:|CPU|:',prelist[1])[4])
prod01_CPU_actv = int(re.split('Activated memory|:|Disk|:|CPU|:',prelist[1])[6])
#print prelist[2]
prod01_memory_cons = int(re.split('memory consumed|:|Disk|:|CPU|:',prelist[2])[2])
prod01_Disk_cons = int(re.split('memory consumed|:|Disk|:|CPU|:',prelist[2])[4])
prod01_CPU_cons = int(re.split('memory consumed|:|Disk|:|CPU|:',prelist[2])[6])
#print prelist[4]
prod01_memory_unused = int(re.split('memory unused|:|Disk|:|CPU|:',prelist[4])[2])
prod01_Disk_unused = int(re.split('memory unused|:|Disk|:|CPU|:',prelist[4])[4])
prod01_CPU_unused = int(re.split('memory unused|:|Disk|:|CPU|:',prelist[4])[6])
elif server_name == 'prod02':
#print prelist[1]
prod02memory_actv = int(re.split('Activated memory|:|Disk|:|CPU|:',prelist[1])[2])
prod02Disk_actv = int(re.split('Activated memory|:|Disk|:|CPU|:',prelist[1])[4])
prod02CPU_actv = int(re.split('Activated memory|:|Disk|:|CPU|:',prelist[1])[6])
#print prelist[2]
prod02memory_cons = int(re.split('memory consumed|:|Disk|:|CPU|:',prelist[2])[2])
prod02Disk_cons = int(re.split('memory consumed|:|Disk|:|CPU|:',prelist[2])[4])
prod02CPU_cons = int(re.split('memory consumed|:|Disk|:|CPU|:',prelist[2])[6])
#print prelist[4]
prod02memory_unused = int(re.split('memory unused|:|Disk|:|CPU|:',prelist[4])[2])
prod02Disk_unused = int(re.split('memory unused|:|Disk|:|CPU|:',prelist[4])[4])
prod02CPU_unused = int(re.split('memory unused|:|Disk|:|CPU|:',prelist[4])[6])
else
#assign all varaiables 0
.....
proc_item["logtime"] = str(t1)
proc_item["prod01_memory_actv"] = prod01_memory_actv
proc_item["prod01_Disk_actv"] = prod01_Disk_actv
proc_item["prod01_CPU_actv"] = prod01_CPU_actv
......
#for all otehr variables...
proc_data.append(proc_item)
with open("./proc_"+ str(date.today()) + ".txt", 'a+') as f:
json.dump(proc_data, f)
f.write("\n")
I have some basic knowledge on python.
- Just using string array indices
hostmtrcs = "Server:prod01 Available memory:20480 Disk:200 CPU:4 Used memory:12438 Disk:120 CPU:3 Unused memory:8042 " \
"Disk:80 CPU:1 Server:prod02 Available memory: 40960 Disk:500 CPU:8 Used memory:20888 Disk:320 CPU:3 Unused " \
"memory:20072 Disk:180 CPU:5 "
datasplt = hostmtrcs.split(":")
hstname = ''
attrkey = ''
attrvalue = ''
for word in range(0, datasplt.__len__()):
if not datasplt[word].__contains__("Server"):
elmnt = datasplt[word].split(" ")
if datasplt[word].__contains__('prod'):
hstname = elmnt[0].lower()
if elmnt.__len__() == 3:
attrkey = elmnt[1].lower() + "_" + elmnt[2].lower() # attrkey
else:
attrkey = elmnt[1]
# retreive the value from the next element in the 1st attry datasplit
if word != datasplt.__len__() - 1:
nxtelmnt = datasplt[word + 1].split(" ")
attrvalue = nxtelmnt[0] # sattrvalue frm next element
finalfrmt = '{' + '"' +hstname + "_" + attrkey + '"' + ":" + attrvalue + '}'
print(finalfrmt)
I think you can do it with dict then just dump over json.(in your case i dont think its valid json but its needs so as per your request i have dump dict over json) i havn't validates keys, i am assuming you get dictionary data correct.
d = { 'Server':'prod01',
'Available memory': 20480,
'Disk':200,
'CPU':4}
import json
s = json.dumps({str(d['Server']+"_"+key).replace(' ','_'):value for key,value in d.items()})
print(json.loads(s))
>>> {'prod01_Server': 'prod01', 'prod01_Available memory': 20480, 'prod01_Disk': 200, 'prod01_CPU': 4}
You should split the input text, section by section, according to what you're looking for.
data = '''Server:prod01
Available memory: 20480 Disk:200 CPU:4
Used memory:12438 Disk:120 CPU:3
Unused memory:8042 Disk:80 CPU:1
Server:prod02
Available memory: 40960 Disk:500 CPU:8
Used memory:20888 Disk:320 CPU:3
Unused memory:20072 Disk:180 CPU:5'''
import re
import json
print(json.dumps({'_'.join((s, l.split(' ', 1)[0], k)).lower(): int(v) for s, d in [i.split('\n', 1) for i in data.split('Server:') if i] for l in d.split('\n') for k, v in re.findall(r'(\w+):\s*(\d+)', l)}))
This outputs:
{"prod01_available_memory": 20480, "prod01_available_disk": 200, "prod01_available_cpu": 4, "prod01_used_memory": 12438, "prod01_used_disk": 120, "prod01_used_cpu": 3, "prod01_unused_memory": 8042, "prod01_unused_disk": 80, "prod01_unused_cpu": 1, "prod02_available_memory": 40960, "prod02_available_disk": 500, "prod02_available_cpu": 8, "prod02_used_memory": 20888, "prod02_used_disk": 320, "prod02_used_cpu": 3, "prod02_unused_memory": 20072, "prod02_unused_disk": 180, "prod02_unused_cpu": 5}
I wrote a little script which scrapes a platform for job advertisments, everything working pretty fine but really slow, since im iterating through up to 200 advertisments for information. While I still think I could code some stuff better to make it run faster aswell, the fact that I couldnt get multiprocessing working here is what bothers me most.
These are the functions, which do the main work, i was trying to add an intern function for the for loop in def get_all_job_details() to map it, but it would always throw an PicklingError or sometimes i got "Expected exactly 2 arguments 3 given" in open_file() which i cant understand tbh.
def get_job_links(section_URL):
soup = make_soup(section_URL)
internerLink = soup.find_all("a", "internerLink primaerElement")
job_links = [BASE_URL + link["href"] for link in internerLink]
return job_links
def get_all_job_links(section_URL):
all_job_links = []
for page in range(1, PAGE_COUNT + 1):
newURL = section_URL[:-1] + str(page)
all_job_links.extend(get_job_links(newURL))
return all_job_links
def get_job_details(job_URL):
soup = make_soup(job_URL)
details = {'job_URL': job_URL, 'refnr': '', 'firmName': '',
'fName': '', 'sName': '', 'adressStr': '',
'adressPlz': '', 'adressOrt': '', 'email': '',
'jobtype': '', 'gender': '', 'status': ''}
[details.update({'refnr': refnr.text}) for refnr in soup.findAll(id=re.compile("referenznummer"))]
[details.update({'firmName': firmName.text}) for firmName in
soup.findAll(id=re.compile("ruckfragenundbewerbungenan_-2147483648"))]
[details.update({'fName': fName.text + ' '}) for fName in soup.findAll(id=re.compile("vorname_-2147483648"))]
[details.update({'sName': sName.text}) for sName in soup.findAll(id=re.compile("nachname_-2147483648"))]
[details.update({'adressStr': adressStr.text}) for adressStr in
soup.findAll(id=re.compile("ruckfragenUndBewerbungenAn.wert\['adresse'\]Strasse_-2147483648"))]
[details.update({'adressPlz': adressPlz.text}) for adressPlz in
soup.findAll(id=re.compile("ruckfragenUndBewerbungenAn.wert\['adresse'\]Plz_-2147483648"))]
[details.update({'adressOrt': adressOrt.text}) for adressOrt in
soup.findAll(id=re.compile("ruckfragenUndBewerbungenAn.wert\['adresse'\]Ort_-2147483648"))]
[details.update({'email': str(email['href'])[7:]}) for email in
soup.findAll(id=re.compile("vermittlung.stellenangeboteverwalten.detailszumstellenangebot.email"))]
jobtype = soup.b
if jobtype:
jobtype = soup.b.text
else:
jobtype = ''
if jobtype.find("Anwendungsentwicklung") > -1:
details.update({'jobtype': u"Fachinformatiker für Anwendungsentwicklung"})
elif jobtype.find("Systemintegration") > -1:
details.update({'jobtype': u"Fachinformatiker für Systemintegration"})
elif jobtype.find("Medieninformatik") > -1:
details.update({'jobtype': u"Medieninformatiker"})
elif jobtype.find("Informatikkaufmann") > -1:
details.update({'jobtype': u"Informatikkaufmann"})
elif jobtype.find("Systemkaufmann") > -1:
details.update({'jobtype': u"IT-Systemkaufmann"})
else:
details.update({'jobtype': u"Informatiker"})
soup.find("div", {"class": "ausklappBox"}).decompose()
genderdiv = str(soup.div)
gender = ''
if genderdiv.find("Frau") > -1:
gender += "Frau "
if genderdiv.find("Herr") > -1:
gender += "Herr "
if len(gender) > 5:
gender = ''
details.update({'gender': gender})
return details
def get_all_job_details(section_URL):
all_job_details = []
all_job_links = get_all_job_links(section_URL)
for i in range(len(all_job_links)):
all_job_details.append(get_job_details(all_job_links[i]))
printProgress(i, len(all_job_links) - 1, prefix='Progress:', suffix='Complete', barLength=50)
return all_job_details
def printProgress(iteration, total, prefix='', suffix='', decimals=2, barLength=100):
"""
Call in a loop to create terminal progress bar
#params] =
iteration - Required : current iteration (Int)
total - Required : total iterations (Int)
prefix - Optional : prefix string (Str)
suffix - Optional : suffix string (Str)
decimals - Optional : number of decimals in percent complete (Int)
barLength - Optional : character length of bar (Int)
"""
filledLength = int(round(barLength * iteration / float(total)))
percents = round(100.00 * (iteration / float(total)), decimals)
bar = '#' * filledLength + '-' * (barLength - filledLength)
Sys.stdout.write('%s [%s] %s%s %s\r' % (prefix, bar, percents, '%', suffix)),
Sys.stdout.flush()
if iteration == total:
print("\n\n")
So how do I do it correctly?
I am working on a program in Python however I am getting the following error when I run it through the terminal:
Traceback (most recent call last):
File "packetSniffer.py", line 120, in <module>
main()
File "packetSniffer.py", line 27, in main
(version, headerLength, timeToLive, protocol, source, target, data) = ip(data)
ValueError: too many values to unpack (expected 7)
However I am doing everything the proper way (I am assuming because I don't see anything wrong with my code). I hope a fresh set of eyes will be able to spot my issue.
Here is my entire program:
import struct
import textwrap
import socket
TAB_1 = '\t - '
TAB_2 = '\t\t - '
TAB_3 = '\t\t\t - '
TAB_4 = '\t\t\t\t - '
DATA_TAB_1 = '\t '
DATA_TAB_2 = '\t\t '
DATA_TAB_3 = '\t\t\t '
DATA_TAB_4 = '\t\t\t\t '
def main():
connection = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.ntohs(3))
while True:
rawData, address = connection.recvfrom(65535)
reciever_mac, sender_mac, ethernetProtocol, data = ethernet_frame(rawData)
print('\nEthernet Frame: ')
print(TAB_1 + 'Destination: {}, Source: {}, Protocol: {}'.format(reciever_mac, sender_mac, ethernetProtocol))
#Make sure you are using Ethernet protocol 8
if ethernetProtocol == 8:
(version, headerLength, timeToLive, protocol, source, target, data) = ip(data)
print(TAB_1 + 'IP Packet:')
print(TAB_2 + 'Version: {}, Header Length: {}, TTL: {}'.format(version, headerLength, timeToLive))
print(TAB_2 + 'Protocol: {}, Source: {}, Target: {}'.format(protocol, source, target))
if protocol == 1:
icmpType, code, checkSum, data = icmpPackets(data)
print(TAB_1 + 'ICMP Packet:')
print(TAB_2 + 'Type: {}, Code: {}, Checksum: {},'.format(icmpType, code, checkSum))
print(TAB_2 + 'Data:')
print(formatMultiLine(DATA_TAB_3, data))
elif protocol == 6:
(sourcePort, destinationPort, sequence, acknowledgement, flagURG, flagACK, flagPSH, flagRST, flagSYN, flagFIN, data) = tcpSegment(data)
print(TAB_2 + 'Source Port: {}, Destination Port: {}'.format(sourcePort, destinationPort))
print(TAB_2 + 'Sequence: {}, Acknowledgment: {}'.format(sequence, acknowledgement))
print(TAB_2 + 'Flags:')
print(TAB_3 + 'URG: {}, ACK: {}, PSH: {}'.format(flagURG, flagACK, flagPSH))
print(TAB_3 + 'RST: {}, SYN: {}, FIN:{}'.format(flagRST, flagSYN, flagSYN))
print(formatMultiLine(DATA_TAB_3, data))
elif protocol == 17:
(sourcePort, destinationPort, length, data) = udpSegment(data)
print(TAB_1 + 'UDP Segment:')
print(TAB_2 + 'Source Port: {}, Destination Port: {}, Length: {}'.format(sourcePort, destinationPort, length))
else:
print(TAB_1 + 'Other IPv4 Data:')
print(formatMultiLine(DATA_TAB_2, data))
else:
print('Ethernet Data:')
print(formatMultiLine(DATA_TAB_1, data))
# Unpack ethernet frame
def ethernet_frame(data):
reciever_mac, sender_mac, protocol = struct.unpack('! 6s 6s H', data[:14])
return getMacAddress(reciever_mac), getMacAddress(sender_mac), socket.htons(protocol), data[14:]
# Convert the Mac address from the jumbled up form from above into human readable format
def getMacAddress(bytesAddress):
bytesString = map('{:02x}'.format, bytesAddress)
macAddress = ':'.join(bytesString).upper()
return macAddress
#Unpack IP header data
def ip_packet(data):
versionHeaderLength = data[0]
version = versionHeaderLength >> 4
headerLength = (versionHeaderLength & 15) * 4
timeToLive, protocol, source, target = struct.unpack('! 8x B B 2x 4s 4s', data[:20])
return version, headerLength, timeToLive, protocol, ip(source), ip(target), data[headerLength:]
#Returns properly formatted IP address
def ip(address):
return '.'.join(map(str, address))
#Unpack ICMP packets
def icmpPackets(data):
icmpType, code, checkSum = struct.unpack('! B B H', data[:4])
return icmpType, code, checkSum, data[4:]
#Unpack TCP segments:
def tcpSegment(data):
(sourcePort, destinationPort, sequence, acknowledgement, offsetReservedFlags) = struct.unpack('! H H L L H', data[:14])
offset = (offsetReservedFlags >> 12) * 4
flagURG = (offsetReservedFlags & 32) >> 5
flagACK = (offsetReservedFlags & 16) >> 4
flagPSH = (offsetReservedFlags & 8) >> 3
flagRST = (offsetReservedFlags & 4) >> 2
flagSYN = (offsetReservedFlags & 2) >> 1
flagFIN = offsetReservedFlags & 1
return sourcePort, destinationPort, sequence, acknowledgement, flagURG, flagACK, flagPSH, flagRST, flagSYN, flagFIN, data[offset:]
#Unpack UDP segments:
def udpSegment(data):
sourcePort, destinationPort, size = struct.unpack('! H H 2x H', data[:8])
return sourcePort, destinationPort, size, data[8:]
#Breaks down and formats large, multi-lined data
def formatMultiLine(prefix, string, size = 80):
size -= len(prefix)
if isinstance(string, bytes):
string = ''.join(r'\x{:02X}'.format(byte) for byte in string)
if size % 2:
size -= 1
return '\n'.join([prefix + line for line in textwrap.wrap(string, size)])
main()
Thanks in advance!
Right before the errant line:
(version, headerLength, timeToLive, protocol, source, target, data) = ip(data)
you should place the following:
print(data)
print(ip(data))
The output of that should then show you exactly what the problem is - this is Debugging 101 stuff, it's almost always better to have more information than less when trying to debug your code.
In this case, it's almost guaranteed that ip(data) will be returning a number of items other than seven.
This seems to be ip(data) returns a seq with more than 7 elems.
Try this:
(version, headerLength, timeToLive, protocol, source, target, data) = ip(data)[:7]
the problem here is yours ip function only return a string, but you want to extract a bunch of stuff that it simple can't be extracted by just unpacking, you need to redefine the ip function to return all that stuff or change how you use it.
By the way, there is a way to in case of a larger sequence put all the remaining stuff by using * in one, and only one, of the variables in your unpack list python make some calculation such that everyone get a part od the data that is going to be unpacked
>>> test="255.255.255.255"
>>> a,b,c,d,e,f,g,*h=test
>>> a
'2'
>>> b
'5'
>>> c
'5'
>>> d
'.'
>>> h
['.', '2', '5', '5', '.', '2', '5', '5']
>>>
>>> *a,b,c,d,e,f,g,h=test
>>> a
['2', '5', '5', '.', '2', '5', '5', '.']
>>> b
'2'
>>> c
'5'
>>> a,b,*c,d,e,f,g,h=test
>>> a
'2'
>>> b
'5'
>>> c
['5', '.', '2', '5', '5', '.', '2', '5']
>>> d
'5'
>>>
and as you can see, unpacking a string will only give you a character...
got a section of code that should search through a file to see it search phase is contained and then return data assigned to it, however it always returns none even though it is in the file and i can not see why it would fail
r Goblin500 IspSUjBIQ/LJ0k18VbKIO6mS1oo gorgBf6uW8d6we7ARt8aA6kgiV4 2014-08-12 06:11:58 82.26.108.68 9001 9030
s Fast HSDir Running V2Dir Valid
v Tor 0.2.4.23
w Bandwidth=21
p reject 1-65535
is the line of code i want to read
this is how i am trying to find the value :
def getRouter(nm):
for r in router.itervalues():
if r['nick'] == nm:
return r
return None
.
print getRouter("Goblin500")
and this is how the contents of the file is Parse the consensus into a dict:
# Parse the consensus into a dict
for l in consensus_txt.splitlines():
q = l.strip().split(" ")
if q[0] == 'r': #router descriptor
rfmt = ['nick', 'identity', 'digest', 'pubdate', 'pubtime', 'ip', 'orport', 'dirport']
data = dict(zip(rfmt, q[1:]))
idt= data['identity']
idt += "=" * (4-len(idt)%4) # pad b64 string
ident = data['identity'] = base64.standard_b64decode(idt)
data['identityhash'] = binascii.hexlify(ident)
data['identityb32'] = base64.b32encode(ident).lower()
router[ident] = data
curRouter = ident
if q[0] == 's': #flags description - add to tally totals too
router[curRouter]['flags'] = q[1:]
for w in q[1:]:
if flags.has_key(w):
flags[w]+=1
else:
flags[w] = 1
total += 1
if q[0] == 'v':
router[curRouter]['version'] = ' '.join(q[1:])
what have i missed ?
thanks
You have an error in your original string parsing. This prevents you from matching the values later. Sample code that proves the parsing is wrong:
q = 'r Goblin500 IspSUjBIQ/LJ0k18VbKIO6mS1oo gorgBf6uW8d6we7ARt8aA6kgiV4 2014-08-12 06:11:58 82.26.108.68 9001 9030'
rfmt = ['nick', 'identity', 'digest', 'pubdate', 'pubtime', 'ip', 'orport', 'dirport']
data = dict(zip(rfmt, q[1:]))
print(data)
# {'pubdate': 'b', 'dirport': '5', 'ip': 'i', 'orport': 'n', 'nick': ' ', 'identity': 'G', 'digest': 'o', 'pubtime': 'l'}
print(data['nick'])
# prints out a single space
Basically, the q[1:] portion of the zip statement is only grabbing the first character of the string. I think what you want is q.split()[1:] instead. This will split the string on spaces, convert it to a list and then ignore the first element.