I'm trying to parse question field in a DNS packet where I can read domain and DNS response from a DNS server. I can extract a DNS header, but I'm having trouble to parse the question field because the size of the data is unknown.
I follow this example, but the part of extracting the question field is not working.
What I need is someone to show me the way to do it properly.
I have this code where everything is right...
This is my code:
#!/usr/bin/env python3
from socket import *
import struct
import binascii
def ethernet_frame(raw_data):
mac_dest, mac_src, protocol = struct.unpack('! 6s 6s H',
raw_data[:14])
return byte_to_hex_mac(mac_dest), byte_to_hex_mac(mac_src),
htons(protocol), raw_data[14:]
def byte_to_hex_mac(mac_bytes):
addr = binascii.hexlify(mac_bytes).decode("ascii")
return ":".join([addr[i:i+2] for i in range(0,12,2)])
def data_packet_udp(data):
tuple_data_udp = struct.unpack('! H H H H', data[:8])
port_src = tuple_data_udp[0]
port_dest = tuple_data_udp[1]
udp_len = tuple_data_udp[2]
udp_checksum = tuple_data_udp[3]
return port_src, port_dest, udp_len, udp_checksum, data[8:]
def data_packet_ipv4(data):
tuple_data_ipv4 = struct.unpack("!BBHHHBBH4s4s", data[:20])
version = tuple_data_ipv4[0]
header_len = version >> 4
type_service = tuple_data_ipv4[1]
length_total = tuple_data_ipv4[2]
identification = tuple_data_ipv4[3]
offset_fragment = tuple_data_ipv4[4]
ttl = tuple_data_ipv4[5]
protocols = tuple_data_ipv4[6]
checksum_header = tuple_data_ipv4[7]
ip_src = inet_ntoa(tuple_data_ipv4[8])
ip_dest = inet_ntoa(tuple_data_ipv4[9])
length_header_bytes = (version & 15) * 4
return version, header_len, type_service, + \
length_total, identification, offset_fragment, + \
ttl, protocols, checksum_header, ip_src, ip_dest,
data[length_header_bytes:]
def data_packet_dns(data):
tuple_data_dns = struct.unpack('!HHHHHH', data[:12])
identification = tuple_data_dns[0]
flags = tuple_data_dns[1]
number_queries = tuple_data_dns[2]
number_response = tuple_data_dns[3]
number_authority = tuple_data_dns[4]
number_additional = tuple_data_dns[5]
qr = (flags & 32768) != 0
opcode = (flags & 30720 ) >> 11
aa = (flags & 1024) != 0
tc = (flags & 512) != 0
rd = (flags & 256) != 0
ra = (flags & 128) != 0
z = (flags & 112) >> 4
rcode = flags & 15
return identification, flags, number_queries, number_response, + \
number_authority, number_additional, qr, opcode, aa, tc, + \
rd, ra, z, rcode
sock = socket(AF_PACKET, SOCK_RAW, ntohs(0x0003))
while True:
raw_dados, addr = sock.recvfrom(65536)
mac_dest, mac_src, protocol, payload = ethernet_frame(raw_dados)
if protocol == 8:
( version, header_len, type_service,
length_total, identification, offset_fragment,
ttl, protocols, checksum_header,
ip_src, ip_dest, data ) = data_packet_ipv4(payload)
if protocols == 17:
port_src, port_dest, udp_len, udp_checksum, data =
data_packet_udp(data)
print("--------- HEADER UDP ----------")
print("Port Source : {}".format(port_src))
print("Port Dest : {}".format(port_dest))
print("UDP Length : {}".format(udp_len))
print("UDP Checksum : {}\n".format(udp_checksum))
if port_src == 53 or port_dest == 53:
(identification, flags, number_queries, \
number_response,number_authority,number_additional, \
qr, opcode, aa, tc, rd, ra, z, rcode) = data_packet_dns(data)
print("\t--------- HEADER DNS ----------")
print("\tidentification : {}".format(identification))
print("\tFlags : {}".format(flags))
print("\tnumber_queries : {}".format(number_queries))
print("\tnumber_response : {}".format(number_response))
print("\tnumber_authority : {}".format(number_authority))
print("\tnumber_additional : {}".format(number_additional))
print("\tQr : {}".format(qr))
print("\tOpcode : {}".format(opcode))
print("\tAA : {}".format(aa))
print("\tTC : {}".format(tc))
print("\tRD : {}".format(rd))
print("\tRA : {}".format(ra))
print("\tZ : {}".format(z))
print("\tRCODE : {}".format(rcode))
I am new to python and I am trying to write a code to send hex serial data to a radio and receive hex data in response. radio_init_buf variable store the hex data to be sent. The last two bytes with store checksum. radio_init_buf[3] tells the size.
import sys
import glob
import numpy as np
import serial
class serial_communication():
PORT = 'COM2'
# RETURN_VALUE = None
def list_serial_ports(self):
""" Lists serial port names
:raises EnvironmentError:
On unsupported or unknown platforms
:returns:
A list of the serial ports available on the system
"""
if sys.platform.startswith('win'):
ports = ['COM%s' % (i + 1) for i in range(0,10)]
elif sys.platform.startswith('linux') or sys.platform.startswith('cygwin'):
# this excludes your current terminal "/dev/tty"
ports = glob.glob('/dev/tty[A-Za-z]*')
elif sys.platform.startswith('darwin'):
ports = glob.glob('/dev/tty.*')
else:
raise EnvironmentError('Unsupported platform')
result = []
for port in ports:
try:
s = serial.Serial(port)
s.close()
result.append(port)
except (OSError, serial.SerialException):
pass
return result
def serial_open(self):
self.ser = serial.Serial()
self.ser.baudrate = 9600
self.ser.port = sc.PORT
self.ser.parity = serial.PARITY_NONE
self.ser.stopbits = serial.STOPBITS_ONE
self.ser.bytesize = serial.EIGHTBITS
self.ser.writeTimeout = 1000
self.ser.timeout = 1000
try:
self.ser.open()
print("Port OPENED")
self.initialize(self.ser)
except Exception as e:
print("error opening serial port: " + str(e))
exit()
return self.ser
def checksum(self, crc_packet, crc_packet_length):
crc_table= np.array([0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241,
0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440,
0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40,
0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40,
0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41,
0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641,
0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040,
0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240,
0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441,
0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41,
0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840,
0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40,
0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640,
0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041,
0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240,
0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441,
0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41,
0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840,
0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41,
0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640,
0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041,
0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241,
0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440,
0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40,
0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841,
0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40,
0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41,
0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040],dtype=np.uint16)
saved_crc_byte1 = crc_packet[crc_packet_length - 1]
saved_crc_byte2 = crc_packet[crc_packet_length - 2]
crc_packet[crc_packet_length - 1] = 0
crc_packet[crc_packet_length - 2] = 0
crc = 0
for crc_loop in range(0,crc_packet_length):
crc = (crc >> 8) ^ crc_table[(crc ^ crc_packet[crc_loop]) & 0xFF]
def initialize(self,serial_port):
ser = serial_port
if ser.isOpen():
print("Initialising...")
try:
ser.flushInput() # flush input buffer, discarding all its contents
ser.flushOutput() # flush output buffer, aborting current output
# and discard all that is in buffer
# write data
#f = open('F:/output.txt', 'wb')
radio_init_buf = np.array([0xAA, 0x00, 0x00, 0x08, 0x09, 0x32, 0x0, 0x0],dtype=np.uint8)
#radio_init_buf="\xAA\x00\x00\x08\x09\x32\x00\x00"
print(radio_init_buf)
self.checksum(radio_init_buf,radio_init_buf[3])
print(radio_init_buf)
ser.write(radio_init_buf)
serial.time.sleep(0.5) # give the serial port sometime to receive the data
#return_value = ser.read(7)
print(return_value)
print("Initialisation Complete")
#comm Link Check
print("Communication Link Checking..")
comm_check_buf = np.array([0xAA, 0x06, 00, 6, 0x0B, 0x70],dtype=np.uint8)
ser.write(comm_check_buf)
print("Link Check Complete")
#clear non-volatile memory
clear_nvm_buf = np.array([0xAA, 0x82, 00, 7, 1, 0, 0],dtype=np.uint8)
self.checksum(clear_nvm_buf, clear_nvm_buf[3])
ser.write(clear_nvm_buf)
#ser.close()
except Exception as e1:
print ("error communicating...: " + str(e1))
ser.close()
else:
print("cannot open serial port ")
sc = serial_communication()
print(sc.list_serial_ports())
sc.serial_open()
When i run the code i get:
['COM1', 'COM2', 'COM3']
Port OPENED
Initialising...
[170 0 0 8 9 50 0 0]
[170 0 0 8 9 50 0 0]
b'\xaa\x90\x00\x12\x01\x0c\x00'
Initialisation Complete
Communication Link Checking..
Link Check Complete
Instead of [170 0 0 8 9 50 0 0], i want the hex data.
Also, it is not returning radio_init_buf with checksum. The result after calling checksum is same.
Displaying in hex:
for n in radio_init_buf:
print("{:#x}".format(n), end='')
print()
{:#x} - a format string, #: adds the 0x prefix, x: presentation will be in hex,
In one line:
print(("{:#x} "*len(radio_init_buf)).format(*radio_init_buf))
It creates a string of length len(radio_init_buf).
In *radio_init_buf , '*' unpacks the list.
i try to send a selfmade tcp-packet via raw socket in python3 (with windows 10). Inside the ip-header i want to set protocol to TCP (=6).
The paket i send is:
E\x00\x00\x00\xd41\x00\x00\xff\x06\x00\x00\xc0\xa8\xb29\xc0\xa8\xb2\x01
but I receive (and wireshark detects the same)
E\x00\x00FN\xe7\x00\x00\x80\xff\x00\x00\n\xac\x02e\n\xac
so now it is 255 (uknown)
srcport = 11001
def sendTCP(dest_ip, dest_port,fin, syn, rst, psh, ack, urg):
payload = b'[TESTING]\n'
ip = make_ip(socket.IPPROTO_TCP, source_ip, dest_ip)
tcp = make_tcp(srcport, dest_port, payload, 123, 0, fin, syn, rst, psh, ack, urg)
packet = ip + tcp + payload
s = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
s.sendto(packet, (dest_ip, 0))
ans = s.recv(1024)
print(ans)
def make_ip(proto, srcip, dstip, ident=54321):
saddr = socket.inet_aton(srcip)
daddr = socket.inet_aton(dstip)
ihl_ver = (4 << 4) | 5
return struct.pack('!BBHHHBBH4s4s' ,
ihl_ver, 0, 0, ident, 0, 255, proto, 0, saddr, daddr)
def make_tcp(srcport, dstport, payload, seq=123, ackseq=0,
fin=False, syn=False, rst=False, psh=False, ack=False, urg=False,
window=5840):
offset_res = (5 << 4) | 0
flags = (fin | (syn << 1) | (rst << 2) |
(psh <<3) | (ack << 4) | (urg << 5))
return struct.pack('!HHLLBBHHH',
srcport, dstport, seq, ackseq, offset_res,
flags, window, 0, 0)
if __name__ == '__main__':
sendTCP('10.172.2.101',80, False, True, False, False, False, False)
I've a setup with Nginx, uWSGI and a Python Flask app. Below you can find server directive from Nginx configuration:
location /api {
try_files $uri #api;
}
location #api {
include uwsgi_params;
uwsgi_pass 127.0.0.1:3031;
}
I start uWSGI with uwsgi --ini /etc/uwsgi.ini. That file looks like this:
[uwsgi]
uid = root
gid = root
socket = 127.0.0.1:3031
module = iris.api
callable = app
Requests to / work fine, Nginx returns the "Welcome to Nginx"-page.
But request to /api are failing. The first request at /api/analog_output/1 is passed via uWSGI to the Python app. The Python app returns with a HTTP 200 response, but Nginx doesn't finish the request by sending this response back to the client.
--- Operational MODE: single process --- WSGI app 0 (mountpoint='') ready in 11 seconds on interpreter 0x1567e8 pid: 957 (default app)
--- uWSGI is running in multiple interpreter mode --- spawned uWSGI worker 1 (and the only) (pid: 957, cores: 1)
[pid: 957|app: 0|req: 1/1] 10.0.0.125 () {42 vars in 712 bytes} [Sun Jan 14 17:22:49 2007] GET /api/analog_output/1 => generated 135 bytes in 66 msecs (HTTP/1.1 200) 2 headers in 72 bytes (1 switches on core 0)
Below you can find the output of strace bind to the Nginx worker.
17:27:39.127453 gettimeofday({1168795659, 128279}, NULL) = 0
17:27:39.129180 write(4, "2007/01/14 17:27:39 [info] 970#0"..., 83) = 83
17:27:39.130169 epoll_wait(8, {{EPOLLIN, {u32=651592, u64=2410198208213320}}}, 512, -1) = 1
17:27:44.680001 gettimeofday({1168795664, 680353}, NULL) = 0
17:27:44.682734 accept4(6, {sa_family=AF_INET, sin_port=htons(53845), sin_addr=inet_addr("10.0.0.125")}, [16], SOCK_NONBLOCK) = 3
17:27:44.685625 epoll_ctl(8, EPOLL_CTL_ADD, 3, {EPOLLIN|EPOLLRDHUP|EPOLLET, {u32=651816, u64=651816}}) = 0
17:27:44.688045 epoll_wait(8, {{EPOLLIN, {u32=651816, u64=651816}}}, 512, 60000) = 1
17:27:44.690552 gettimeofday({1168795664, 691682}, NULL) = 0
17:27:44.693043 recv(3, "GET /api/analog_output/1 HTTP/1."..., 1024, 0) = 426
17:27:44.695848 stat64("/usr/html/api/analog_output/1", 0xbeb8f730) = -1 ENOENT (No such file or directory)
17:27:44.698599 epoll_ctl(8, EPOLL_CTL_MOD, 3, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=651816, u64=13170497834292212264}}) = 0
17:27:44.701146 getsockname(3, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("10.0.0.195")}, [16]) = 0
17:27:44.703848 socket(PF_INET, SOCK_STREAM, IPPROTO_IP) = 10
17:27:44.706386 ioctl(10, FIONBIO, [1]) = 0
17:27:44.708823 epoll_ctl(8, EPOLL_CTL_ADD, 10, {EPOLLIN|EPOLLOUT|EPOLLRDHUP|EPOLLET, {u32=651928, u64=2525337691484824}}) = 0
17:27:44.711468 connect(10, {sa_family=AF_INET, sin_port=htons(3031), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
17:27:44.714574 epoll_wait(8, {{EPOLLOUT, {u32=651816, u64=13170497834292212264}}, {EPOLLOUT, {u32=651928, u64=2525337691484824}}}, 512, 60000) = 2
17:27:44.717109 gettimeofday({1168795664, 718064}, NULL) = 0
17:27:44.719461 recv(3, 0xbeb8f89c, 1, MSG_PEEK) = -1 EAGAIN (Resource temporarily unavailable)
17:27:44.721999 getsockopt(10, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
17:27:44.724476 writev(10, [{"\0\310\2\0\f\0QUERY_STRING\0\0\16\0REQUEST_ME"..., 716}], 1) = 716
17:27:44.729618 epoll_wait(8, {{EPOLLIN|EPOLLOUT, {u32=651928, u64=2525337691484824}}}, 512, 60000) = 1
17:27:44.793473 gettimeofday({1168795664, 794585}, NULL) = 0
17:27:44.796026 recv(10, "HTTP/1.1 200 OK\r\nContent-Type: a"..., 4096, 0) = 207
But now the Nginx's worker hangs with full CPU. Further requests aren't processed.
What is going on? And how can I fix it?
Your location block looks incomplete. Not in front of a machine at the moment, but try adding:
proxy_redirect off;
edit: the #app location block
I am running a custom Python 2.7.3 application on CherryPy in Linux. When I used a service script in /etc/init.d/ to start or stop the service, I encountered a Segmentation Fault (SIGSEGV). Strangely, I did not receive a SIGSEGV if I ran the start or stop command manually from the shell, using "python /path/to/file.py --stop". The service script executes the same command.
After some debugging, by chance, I discovered that my /tmp was mounted with a "noexec" option. I removed the "noexec" option and the application was able to start and stop via the service scripts without any segmentation faults.
When I first encountered the issue, I ran strace and generated a core dump. Nothing from either tool gave me any indication that /tmp was the culprit. My question is this: How could I have used strace or gdb to help me identify that "noexec" on /tmp was causing the segmentation faults?
Here is some output from gdb when analyzing the core dump:
(gdb) bt full
#0 PyObject_Malloc (nbytes=4) at Objects/obmalloc.c:788
bp = 0x7f6b0fd1c6e800 \Address 0x7f6b0fd1c6e800 out of bounds\
pool = 0x7f6b0fd1c000
next = \value optimized out\
size = 0
#1 0x00007f6b0f7fd8e6 in _PyUnicode_New (length=1) at Objects/unicodeobject.c:345
new_size = 4
unicode = 0x3873480
#2 0x00007f6b0f7fdd4e in PyUnicodeUCS2_FromUnicode (u=0x38367cc, size=)
at Objects/unicodeobject.c:461
unicode = \value optimized out\
(There is a lot more output, this is just the first few lines)
Here is some output from strace on the failure:
3046 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.py", O_RDONLY) = 9
3046 fstat(9, {st_mode=S_IFREG|0644, st_size=13310, ...}) = 0
3046 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.pyc", O_RDONLY) = 10
3046 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3046 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fbc9ff9d000
3046 read(10, "\3\363\r\n}\321\322Tc\0\0\0\0\0\0\0\0\5\0\0\0##\2\0sd\2\0\0d\0"..., 4096) = 4096
3046 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3046 read(10, "\0\0\0C#\2\0s\330\0\0\0t\0\0|\0\0t\1\0\203\2\0s\36\0t\0\0|\0"..., 8192) = 8192
3046 read(10, "thon2.7/site-packages/oauthlib/c"..., 4096) = 3755
3046 read(10, "", 4096) = 0
3046 close(10) = 0
3046 munmap(0x7fbc9ff9d000, 4096) = 0
3046 --- SIGSEGV (Segmentation fault) # 0 (0) ---
After fixing the problem, here's a snippet from strace, from the same point where it tries to load oauthlib/common.pyc - notice that the only difference appears to be a brk() before munmap():
3416 open("/usr/local/python2.7/lib/python2.7/site-packages/oauthlib/common.pyc", O_RDONLY) = 10
3416 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3416 mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f5791f2c000
3416 read(10, "\3\363\r\n}\321\322Tc\0\0\0\0\0\0\0\0\5\0\0\0##\2\0sd\2\0\0d\0"..., 4096) = 4096
3416 fstat(10, {st_mode=S_IFREG|0644, st_size=16043, ...}) = 0
3416 read(10, "\0\0\0C#\2\0s\330\0\0\0t\0\0|\0\0t\1\0\203\2\0s\36\0t\0\0|\0"..., 8192) = 8192
3416 read(10, "thon2.7/site-packages/oauthlib/c"..., 4096) = 3755
3416 read(10, "", 4096) = 0
3416 brk(0x372f000) = 0x372f000
3416 close(10) = 0
3416 munmap(0x7f5791f2c000, 4096) = 0
3416 close(9) = 0
What information can help me point the blame at /tmp's mount options?
For those who would have the same problem as I had and find this page:
My CherryPy server.py ran fine on my Win10 system on python3.8 but failed with segmentation fault on my Linux system which had python3.6.1.
Switching to python3.8 on Linux solved my problem.