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...
Related
I'm creating a function to calculate packet capture delay using Python and pcap, but this error happens. I'm taking this function from a C example as I'm new to Python. This is the error:
Traceback (most recent call last):
File "prototype_sniffer_v1.py", line 266, in processing_pkts
Bps = ((pkt + 8) * 8 * 1000000) / (delay) TypeError: unsupported operand type(s) for +: 'LP_c_ubyte' and 'int'
Exception ignored on calling ctypes callback function: <function processing_pkts at 0x7fbed299df70>
This link Gathering Statistics on the network traffic contain the C code example.
This is C example:
#include <stdlib.h>
#include <stdio.h>
#include <pcap.h>
#include <tchar.h>
BOOL LoadNpcapDlls()
{
_TCHAR npcap_dir[512];
UINT len;
len = GetSystemDirectory(npcap_dir, 480);
if (!len) {
fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
return FALSE;
}
_tcscat_s(npcap_dir, 512, _T("\\Npcap"));
if (SetDllDirectory(npcap_dir) == 0) {
fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
return FALSE;
}
return TRUE;
}
void usage();
void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);
void main(int argc, char **argv)
{
pcap_t *fp;
char errbuf[PCAP_ERRBUF_SIZE];
struct timeval st_ts;
u_int netmask;
struct bpf_program fcode;
/* Load Npcap and its functions. */
if (!LoadNpcapDlls())
{
fprintf(stderr, "Couldn't load Npcap\n");
exit(1);
}
/* Check the validity of the command line */
if (argc != 2)
{
usage();
return;
}
/* Open the output adapter */
if ( (fp= pcap_open(argv[1], 100, PCAP_OPENFLAG_PROMISCUOUS,
1000, NULL, errbuf) ) == NULL)
{
fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf);
return;
}
/* Don't care about netmask, it won't be used for this filter */
netmask=0xffffff;
//compile the filter
if (pcap_compile(fp, &fcode, "tcp", 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
/* Free the device list */
return;
}
//set the filter
if (pcap_setfilter(fp, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter.\n");
pcap_close(fp);
/* Free the device list */
return;
}
/* Put the interface in statstics mode */
if (pcap_setmode(fp, MODE_STAT)<0)
{
fprintf(stderr,"\nError setting the mode.\n");
pcap_close(fp);
/* Free the device list */
return;
}
printf("TCP traffic summary:\n");
/* Start the main loop */
pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&st_ts);
pcap_close(fp);
return;
}
void dispatcher_handler(u_char *state,
const struct pcap_pkthdr *header,
const u_char *pkt_data)
{
struct timeval *old_ts = (struct timeval *)state;
u_int delay;
LARGE_INTEGER Bps,Pps;
struct tm ltime;
char timestr[16];
time_t local_tv_sec;
/* Calculate the delay in microseconds from the last sample. This value
* is obtained from the timestamp that the associated with the sample. */
delay = (header->ts.tv_sec - old_ts->tv_sec) * 1000000
- old_ts->tv_usec + header->ts.tv_usec;
/* Get the number of Bits per second */
Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay));
/* ^ ^
| |
| |
| |
converts bytes in bits -- |
|
delay is expressed in microseconds --
*/
/* Get the number of Packets per second */
Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay));
/* Convert the timestamp to readable format */
local_tv_sec = header->ts.tv_sec;
localtime_s(<ime, &local_tv_sec);
strftime( timestr, sizeof timestr, "%H:%M:%S", <ime);
/* Print timestamp*/
printf("%s ", timestr);
/* Print the samples */
printf("BPS=%I64u ", Bps.QuadPart);
printf("PPS=%I64u\n", Pps.QuadPart);
//store current timestamp
old_ts->tv_sec=header->ts.tv_sec;
old_ts->tv_usec=header->ts.tv_usec;
}
void usage()
{
printf("\nShows the TCP traffic load, in bits per second and packets per second."
"\nCopyright (C) 2002 Loris Degioanni.\n");
printf("\nUsage:\n");
printf("\t tcptop adapter\n");
printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n");
exit(0);
}
This is my Python function:
import libpcap as pcap
import ctypes as ct
import socket
import getopt
import os
import time
import funcoes_auxiliares
from struct import *
from libpcap._platform import sockaddr, sockaddr_in, sockaddr_in6
from pcaptestutils import *
pd = ct.POINTER(pcap.pcap_t)()
if not is_windows:
breaksigint = False
#static void sigint_handler(int signum _U_)
def sigint_handler(signum):
global pd
global breaksigint
if breaksigint:
pcap.breakloop(pd)
def main(argv=sys.argv[1:]):
global program_name
program_name = os.path.basename(sys.argv[0])
global pd
global breaksigint
global ip_afinet
global ip_afinet6
# Exceção para os parâmetros
try:
opts, args = getopt.getopt(argv, "i:mnt:" if is_windows else "bi:mnrst:")
except getopt.GetoptError:
usage()
device = None
timeout = 1000
nonblock = 0
immediate = False
if not is_windows:
sigrestart = False
catchsigint = False
for opt, optarg in opts:
if not is_windows and opt == '-b':
breaksigint = True
elif opt == '-i':
device = optarg.encode("utf-8")
elif opt == '-m':
immediate = True
elif opt == '-n':
nonblock = 1
elif not is_windows and opt == '-r':
sigrestart = True
elif not is_windows and opt == '-s':
catchsigint = True
elif opt == '-t':
try:
timeout = int(optarg)
except:
error('Timeout value "{}" is not a number', optarg)
if timeout < 0:
error("Timeout value {:d} is negative", timeout)
if timeout > INT_MAX:
error("Timeout value {:d} is too large (> {:d})",
timeout, INT_MAX)
else:
usage()
expression = args
errbuf = ct.create_string_buffer(pcap.PCAP_ERRBUF_SIZE)
# ----------------------------------------------------------
# Lista de dispositivos disponíveis
if device is None:
deviceList = ct.POINTER(pcap.pcap_if_t)()
if pcap.findalldevs(ct.byref(deviceList), errbuf) == -1:
error("{}", ebuf2str(errbuf))
if not deviceList:
error("Não há interfaces disponíveis para captura")
print('\nAvailable network devices:')
devices = deviceList
while devices:
device = devices.contents
print("\t[*] {}".format(device.name.decode("utf-8")))
devices = device.next
device = deviceList[0].name
ip_tuple = funcoes_auxiliares.getStdIp(deviceList[0])
(ip_afinet, ip_afinet6) = ip_tuple
# print(ip_afinet)
# print(ip_afinet6)
pcap.freealldevs(deviceList)
# ----------------------------------------------------------
errbuf[0] = b"\0"
# if not is_windows:
# # If we were told to catch SIGINT, do so.
# if catchsigint:
# action = sigaction()
# action.sa_handler = sigint_handler
# sigemptyset(ct.byref(action.sa_mask))
# # Should SIGINT interrupt, or restart, system calls?
# action.sa_flags = SA_RESTART if sigrestart else 0
# if sigaction(SIGINT, ct.byref(action), NULL) == -1:
# error("Can't catch SIGINT: {}", strerror(errno))
pd = pcap.create(device, errbuf)
if not pd:
error("{}", ebuf2str(errbuf))
# define o comprimento do instantâneo a ser usado
# em um identificador de captura quando o
# identificador é ativado para snaplen.
status = pcap.set_snaplen(pd, 65535)
if status != 0:
error("{}: pcap.set_snaplen failed: {}",
device2str(device), status2str(status));
if immediate:
try:
status = pcap.set_immediate_mode(pd, 1)
except AttributeError:
error("pcap.set_immediate_mode is not available on this platform")
if status != 0:
error("{}: pcap.set_immediate_mode failed: {}",
device2str(device), status2str(status))
status = pcap.set_timeout(pd, timeout)
if status != 0:
error("{}: pcap.set_timeout failed: {}",
device2str(device), status2str(status))
status = pcap.activate(pd)
if status < 0:
# pcap.activate() failed.
error("{}: {}\n({})",
device2str(device), status2str(status), geterr2str(pd))
elif status > 0:
# pcap.activate() succeeded, but it's warning us
# of a problem it had.
warning("{}: {}\n({})",
device2str(device), status2str(status), geterr2str(pd))
localnet = pcap.bpf_u_int32()
netmask = pcap.bpf_u_int32()
if pcap.lookupnet(device, ct.byref(localnet), ct.byref(netmask), errbuf) < 0:
localnet = pcap.bpf_u_int32(0)
netmask = pcap.bpf_u_int32(0)
warning("{}", ebuf2str(errbuf))
fcode = pcap.bpf_program()
cmdbuf = " ".join(expression).encode("utf-8")
if pcap.compile(pd, ct.byref(fcode), cmdbuf, 1, netmask) < 0:
error("{}", geterr2str(pd))
if pcap.setfilter(pd, ct.byref(fcode)) < 0:
error("{}", geterr2str(pd))
if pcap.setnonblock(pd, nonblock, errbuf) == -1:
error("pcap.setnonblock failed: {}", ebuf2str(errbuf))
# -----------------------------------------
# create a save file for write
savefile = 'testsavefile'
savefile = savefile.encode('utf-8')
pdd = pcap.dump_open_append(pd, savefile)
if not pdd:
error("{}", geterr2str(pd))
# -----------------------------------------
print("\nSniffing on device: \n\t*{}*".format(device2str(device)))
if os.path.exists("qtdPktpTime.txt"):
os.remove("qtdPktpTime.txt")
cont_i = 0
while cont_i <= 10:
# while True:
packet_count = ct.c_int(0)
status = pcap.dispatch(pd, -1, processing_pkts,
ct.cast(ct.pointer(packet_count), ct.POINTER(ct.c_ubyte)))
# execute for write in save file
pcap.dispatch(pd, -1, pcap.dump,
ct.cast(pdd, ct.POINTER(ct.c_ubyte)))
if status < 0:
break
if status != 0:
print("\n{:d} packets seen, {:d} packets counted after "
"pcap.dispatch returns".format(status, packet_count.value))
ps = pcap.stat()
pcap.stats(pd, ct.byref(ps))
print("{:d} ps_recv, {:d} ps_drop, {:d} ps_ifdrop".format(
ps.ps_recv, ps.ps_drop, ps.ps_ifdrop))
print("\n")
cont_i += 1
if status == pcap.PCAP_ERROR_BREAK:
# We got interrupted, so perhaps we didn't manage to finish a
# line we were printing. Print an extra newline, just in case.
print()
print("Broken out of loop from SIGINT handler")
sys.stdout.flush()
if status == pcap.PCAP_ERROR:
# Error. Report it.
print("{}: pcap.dispatch: {}".format(program_name, geterr2str(pd)),
file=sys.stderr)
pcap.freecode(ct.byref(fcode))
pcap.close(pd)
funcoes_auxiliares.plotGraf1()
return 1 if status == -1 else 0
# --------------------------------------------------------------------------------------
# AUXILIAR FUNCTIONS
# --------------------------------------------------------------------------------------
# Convert a string of 6 characters of ethernet address into a dash separated hex string
def eth_addr (a) :
b = "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x" % (ord(a[0]) , ord(a[1]) , ord(a[2]), ord(a[3]), ord(a[4]) , ord(a[5]))
return b
# Função callback usada no processamento dos pacotes
#pcap.pcap_handler
def processing_pkts(arg, hdr, pkt):
counterp = ct.cast(arg, ct.POINTER(ct.c_int))
counterp[0] += 1
old_ts_tv_sec = 0
old_ts_tv_usec = 0
pkt_addr = hdr.contents
pkt_time_cap = pkt_addr.ts
pkt_len = pkt_addr.len
pkt_caplen = pkt_addr.caplen
eth_length = 14
eth_header = pkt[:eth_length]
eth = unpack('!6s6sH' , bytes(eth_header))
eth_protocol = socket.ntohs(eth[2])
count_pkt = 0
delay = (pkt_time_cap.tv_sec - old_ts_tv_sec) * 1000000 - old_ts_tv_usec + pkt_time_cap.tv_usec
Bps = (ct.cast(pkt,ct.POINTER(ct.c_uint64))[1] * 8 * 1000000) / (delay)
Pps = (ct.cast(pkt,ct.POINTER(ct.c_uint64))[0] * 1000000) / delay
old_ts_tv_sec = pkt_time_cap.tv_sec
old_ts_tv_usec = pkt_time_cap.tv_usec
print('Bps: ' + str(int(Bps)))
print('Pps: ' + str(int(Pps)))
time_cap = time.ctime(pkt_time_cap.tv_sec)
# Parser IP packets
if eth_protocol == 8:
ip_header = pkt[eth_length:20+eth_length]
iph = unpack('!BBHHHBBH4s4s' , bytes(ip_header))
version_ihl = iph[0]
version = version_ihl >> 4
ihl = version_ihl & 0xF
iph_length = ihl * 4
ttl = iph[5]
protocol = iph[6]
s_addr = socket.inet_ntoa(iph[8]);
d_addr = socket.inet_ntoa(iph[9]);
# print('Version: ' + str(version) + '| IP Header Length: ' + str(ihl) + ' | ' + 'TTL: ' + str(ttl) + ' | ' + 'Protocol: ' + str(protocol) + ' | ' +'Source Address: ' + str(s_addr) + ' | ' +'Destination Address: ' + str(d_addr) + ' | ' + 'length: ' + str(pkt_len) + ' | ' + 'cap length: ' + str(pkt_caplen) + ' | ' + 'Cap time: ' + str(pkt_time_cap))
print('\nVersion: ' + str(version) + '| IP Header Length: ' + str(ihl) + ' | ' + 'TTL: ' + str(ttl) + ' | ' + 'Protocol: ' + str(protocol) + ' | ' +'Source Address: ' + str(s_addr) + ' | ' +'Destination Address: ' + str(d_addr) + ' | ' + 'length: ' + str(pkt_len))
count_pkt = 0
if s_addr == ip_afinet:
# print('confirma ip')
count_pkt += 1
arq_qtdPktpTime = open("qtdPktpTime.txt", "a")
arq_qtdPktpTime.write(time_cap + ',' + str(counterp[0]) + '\n')
# funcoes_auxiliares.plotGraf1()
# TCP protocol
if protocol == 6:
t = iph_length + eth_length
tcp_header = pkt[t:t+20]
tcph = unpack('!HHLLBBHHH' , bytes(tcp_header))
source_port = tcph[0]
dest_port = tcph[1]
sequence = tcph[2]
acknowledgement = tcph[3]
doff_reserved = tcph[4]
tcph_length = doff_reserved >> 4
print('Source Port: ' + str(source_port) + ' >> Dest Port: ' + str(dest_port) + ' >> Sequence Number: ' + str(sequence) + ' >> Acknowledgement: ' + str(acknowledgement) + ' >> TCP header length: ' + str(tcph_length))
h_size = eth_length + iph_length + tcph_length * 4
# data_size = len(pkt) - h_size
# data_size = pkt_len - h_size
#get data from the packet
data = pkt[h_size:pkt_len]
# print('Data : ' + str(data))
# UDP procotol
elif protocol == 17:
u = iph_length + eth_length
udph_length = 8
udp_header = pkt[u:u+8]
udph = unpack('!HHHH' , bytes(udp_header))
source_port = udph[0]
dest_port = udph[1]
length = udph[2]
checksum = udph[3]
# print('Source Port: ' + str(source_port) + ' >> Dest Port: ' + str(dest_port) + '>> Length: ' + str(length) + ' >> Checksum: ' + str(checksum))
print('Source Port: ' + str(source_port) + ' >> Dest Port: ' + str(dest_port) + ' >> Checksum: ' + str(checksum))
h_size = eth_length + iph_length + udph_length
# data = pkt[h_size:pkt_len]
# print(data)
# pcap.dump
# função para captura e uso de parametros no execução do código no terminal
def usage():
print("Usage: {} [ {} ] [ -i interface ] [ -t timeout] "
"[ expression ]".format(program_name,
"-mn" if is_windows else "-bmnrs"), file=sys.stderr)
sys.exit(1)
# --------------------------------------------------------------------------------------
if __name__.rpartition(".")[-1] == "__main__":
sys.exit(main())
Can help me to solve this ?? I appreciate any tips
The C code the OP is porting and generating an error in Python is:
/* Calculate the delay in microseconds from the last sample. This value
* is obtained from the timestamp that the associated with the sample. */
delay = (header->ts.tv_sec - old_ts->tv_sec) * 1000000
- old_ts->tv_usec + header->ts.tv_usec;
/* Get the number of Bits per second */
Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay));
/* ^ ^
| |
| |
| |
converts bytes in bits -- |
|
delay is expressed in microseconds --
*/
/* Get the number of Packets per second */
Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay));
The Python code is missing the casting and dereferencing of the pkt_data + 8 byte pointer calculation. Since *(LONGLONG*)(pkt_data + 8) == ((LONGLONG*)(pkt_data))[1], the Python code implements cast and dereference of the latter version:
delay = (pkt_time_cap.tv_sec - old_ts_tv_sec) * 1000000 - old_ts_tv_usec + pkt_time_cap.tv_usec
Bps = ct.cast(pkt,ct.POINTER(ct.c_uint64))[1] * 8 * 1000000 / delay
Pps = ct.cast(pkt,ct.POINTER(ct.c_uint64))[0] * 1000000 / delay
Since there isn't a functional example I'll demonstrate by creating a byte pointer to two 64-bit values to test the code is correct. The original code was adding 8 to a byte pointer, casting to a 64-bit pointer and dereferencing it. That's the same thing as casting directly to a 64-bit pointer and indexing the 2nd value, e.g. *(LONGLONG*)(pkt_data + 8) == ((LONGLONG*)(pkt_data))[1]:
>>> import ctypes as ct
>>> data = (ct.c_uint64 * 2)(100,200)
>>> pkt = ct.cast(ct.byref(data), ct.POINTER(ct.c_ubyte))
>>> pkt
<__main__.LP_c_ubyte object at 0x000002D38C9BA5C0>
>>> pkt + 8
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'LP_c_ubyte' and 'int'
Above demonstrates the same error as the OP due to pkt being a byte pointer. Below casts the pointer back to a 64-bit pointer and accesses the 2nd value:
>>> ct.cast(pkt,ct.POINTER(ct.c_uint64))[1]
200
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"])
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}
Whenever I send a SYN packet using my program, I get no reply.I know the server is working because I can connect to it using the normal socket connect() method but when I try using RAW sockets to do it I get no reply, not even an RST.
Here is my packet according to Wireshark
Transmission Control Protocol, Src Port: 5173 (5173), Dst Port: 5005 n (5005), Seq: 0, Len: 0
Source Port: 5173
Destination Port: 5005
[Stream index: 15]
[TCP Segment Len: 0]
Sequence number: 0 (relative sequence number)
Acknowledgment number: 0
Header Length: 40 bytes
Flags: 0x002 (SYN)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...0 .... = Acknowledgment: Not set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..1. = Syn: Set
.... .... ...0 = Fin: Not set
[TCP Flags: **********S*]
Window size value: 53270
[Calculated window size: 53270]
Checksum: 0x9f18 [incorrect, should be 0x90ae (maybe caused by "TCP checksum offload"?)]
Urgent pointer: 0
Options: (20 bytes), Maximum segment size, SACK permitted, Timestamps, No-Operation (NOP), Window scale
Maximum segment size: 65495 bytes
Kind: Maximum Segment Size (2)
Length: 4
MSS Value: 65495
TCP SACK Permitted Option: True
Kind: SACK Permitted (4)
Length: 2
Timestamps: TSval 378701, TSecr 0
Kind: Time Stamp Option (8)
Length: 10
Timestamp value: 378701
Timestamp echo reply: 0
No-Operation (NOP)
Type: 1
0... .... = Copy on fragmentation: No
.00. .... = Class: Control (0)
...0 0001 = Number: No-Operation (NOP) (1)
Window scale: 7 (multiply by 128)
[SEQ/ACK analysis]
And here is my Python code
#!/usr/bin/python
import socket
from struct import *
import random
s = socket.socket()
host = "127.0.0.1"
destination = "127.0.0.1"
CLRF = '\r\n'
#socket.gethostname()
print destination
port = 5173
#s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#s.connect((host, 5005))
try:
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
except socket.error , msg:
print 'Socket could not be created. Error Code : ' + str(msg[0]) + ' Message ' + msg[1]
sys.exit()
ipSource = '192.168.0.106'
#IP header
ipIHL = 5 # Header Length
ipVersion = 4 # ipv4/v6
ipTOS = 0 # type of service
ipTotalLen = 0 ## Kernel will fill correct length apparently
ipPackID = random.randint(1,1000)
#Flags
ipReserved = 0
ipNoFrag = 1
ipMoreFrags = 0
ipFragOffset = 0 #Fragment offset
ipTTL = 64
ipProtocol = socket.IPPROTO_TCP
ipChecksum = 0 # Magic kernel filling in at work again
ipSource = socket.inet_aton (host)
ipDest = socket.inet_aton (destination)
#Packing IP flags
ipFlags = ipMoreFrags + (ipNoFrag << 1) + (ipReserved << 2)
ipFragOffset = (ipFlags << 13) + ipFragOffset
ipIHLVersion = (ipVersion << 4) + ipIHL
headerIP = pack('!BBHHHBBH4s4s',ipIHLVersion, ipTOS, ipTotalLen, ipPackID, ipFragOffset, ipTTL, ipProtocol, ipChecksum, ipSource, ipDest)
#Checksum function
def carry_around_add(a, b):
c = a + b
return (c & 0xffff) + (c >> 16)
def checksum(msg):
s = 0
for i in range(0, len(msg), 2):
w = ord(msg[i]) + (ord(msg[i+1]) << 8)
s = carry_around_add(s, w)
return ~s & 0xffff
#TCP Header
tcpSourcePort = port #Source Port
tcpDestPort = 5005 #Destination Port
tcpSeqNum = 0 #Packet sequence
tcpAckNum = 0 #Ackknowledge Number
tcpOffset = 10 #Size of tcp header 20 bytes
#tcpReserved = 0
#tcpECN = 0
#Control Flags
tcpURG = 0
tcpACK = 0
tcpPSH = 0
tcpRST = 0
tcpSYN = 1
tcpFIN = 0
tcpWindow = socket.htons (5840) #Dunno how this works
tcpChecksum = 0
tcpUrgentPointer = 0
#TCP Options
tcpMaxSegmentSize = (2 << 24) + (4 << 16) + 65495 # Kind + Length + Max Segment Size
tcpSACKPermitted = (4 << 8) + 2#Kind + Length
#Split TCP TImestamps into 2 because too large
tcpTimestampPartOne = (8 << 8) + (10) #Kind + Length
tcpTimestampPartTwo = (378701 << 32) + 0 #Timestamp Value + Timestamp echo reply
tcpNoOp = (0 << 7) + (0 << 5) + 1 #Copy on fragmentation + Class + Number
tcpWindowScale = (3 << 16)+ (3 << 8) + 7 #Kind + Length(Bytes) +Shift CountS
#Combine both due to length issues
tcpNoOpAndWindowScale = (tcpNoOp << 24) + tcpWindowScale
tcpOffsetResult = (tcpOffset << 4) + 0 #Shift 4 bytes to left
#Putting together all the TCP Control Flags
tcpFlags = tcpFIN + (tcpSYN << 1) + (tcpRST << 2) + (tcpPSH << 3) + (tcpACK << 4) + (tcpURG << 5)
#Packing the pseudo TCP header
headerTCP = pack('!HHLLBBHHHLHHQL', tcpSourcePort, tcpDestPort, tcpSeqNum, tcpAckNum, tcpOffsetResult, tcpFlags, tcpWindow, tcpChecksum, tcpUrgentPointer, tcpMaxSegmentSize, tcpSACKPermitted, tcpTimestampPartOne, tcpTimestampPartTwo, tcpNoOpAndWindowScale)
#headerTCP = pack('!HHLLBBHHH', tcpSourcePort, tcpDestPort, tcpSeqNum, tcpAckNum, tcpOffsetResult, tcpFlags, tcpWindow, tcpChecksum, tcpUrgentPointer)
#data = 'GET ./asd HTTP/1.1'
data = ''
#Checksum Calculation
#Pseudo Header Fields
sourceAddr = socket.inet_aton(host)
destAddr = socket.inet_aton(destination)
placeholder = 0
protocol = socket.IPPROTO_TCP
tcpLen = len(headerTCP) + len(data)
psh = pack('!4s4sBBH', sourceAddr, destAddr, placeholder, protocol, tcpLen);
psh = psh + headerTCP + data;
#Calc checksum
tcpChecksumReal = (checksum(psh) << 1)
print(tcpChecksumReal)
#Pack actual tcp header with checksum
headerTCP = pack('!HHLLBBH', tcpSourcePort, tcpDestPort, tcpSeqNum, tcpAckNum, tcpOffsetResult, tcpFlags, tcpWindow) + pack('!H', 40728) + pack ('!H', tcpUrgentPointer) + pack('!LHHQL', tcpMaxSegmentSize, tcpSACKPermitted, tcpTimestampPartOne, tcpTimestampPartTwo, tcpNoOpAndWindowScale)
#Build full packet / ip with tcp with data
packet = headerIP + headerTCP + data
#print [hex(ord(c)) for c in packet]
s.sendto(packet, (destination,0))
Any help would be appreciated, thanks in advance.
Credits to #KenCheung for the answer
Turns out it was the checksum, the checksum from the headers I used as reference also were incorrect but the network card was offloading them.
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.