2015-09-29 22:58:06 +08:00
|
|
|
import socket
|
|
|
|
import select
|
2015-10-08 18:30:36 +08:00
|
|
|
import logging
|
2017-09-25 17:01:48 +08:00
|
|
|
import struct
|
2015-09-29 22:58:06 +08:00
|
|
|
|
2015-09-30 20:05:30 +08:00
|
|
|
DEFAULT_TIMEOUT = 10
|
2015-09-29 22:58:06 +08:00
|
|
|
BANNER_READ = 1024
|
|
|
|
|
2015-10-08 18:30:36 +08:00
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
2015-11-30 16:56:20 +08:00
|
|
|
|
2017-09-25 17:01:48 +08:00
|
|
|
def struct_unpack_tracker(data, index, fmt):
|
|
|
|
"""
|
|
|
|
Unpacks a struct from the specified index according to specified format.
|
|
|
|
Returns the data and the next index
|
|
|
|
:param data: Buffer
|
|
|
|
:param index: Position index
|
|
|
|
:param fmt: Struct format
|
|
|
|
:return: (Data, new index)
|
|
|
|
"""
|
|
|
|
unpacked = struct.unpack_from(fmt, data, index)
|
|
|
|
return unpacked, struct.calcsize(fmt)
|
|
|
|
|
|
|
|
|
|
|
|
def struct_unpack_tracker_string(data, index):
|
|
|
|
"""
|
|
|
|
Unpacks a null terminated string from the specified index
|
|
|
|
Returns the data and the next index
|
|
|
|
:param data: Buffer
|
|
|
|
:param index: Position index
|
|
|
|
:return: (Data, new index)
|
|
|
|
"""
|
|
|
|
ascii_len = data[index:].find('\0')
|
|
|
|
fmt = "%ds" % ascii_len
|
|
|
|
unpacked = struct.unpack_from(fmt, data, index)
|
|
|
|
return unpacked, struct.calcsize(fmt)
|
|
|
|
|
|
|
|
|
2015-09-29 22:58:06 +08:00
|
|
|
def check_port_tcp(ip, port, timeout=DEFAULT_TIMEOUT, get_banner=False):
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
sock.settimeout(timeout)
|
|
|
|
|
|
|
|
try:
|
|
|
|
sock.connect((ip, port))
|
2015-10-08 18:30:36 +08:00
|
|
|
except socket.timeout:
|
2015-11-30 16:56:20 +08:00
|
|
|
return False, None
|
2015-10-08 18:30:36 +08:00
|
|
|
except socket.error, exc:
|
|
|
|
LOG.debug("Check port: %s:%s, Exception: %s", ip, port, exc)
|
2015-11-30 16:56:20 +08:00
|
|
|
return False, None
|
2015-09-29 22:58:06 +08:00
|
|
|
|
|
|
|
banner = None
|
|
|
|
|
|
|
|
try:
|
|
|
|
if get_banner:
|
|
|
|
read_ready, _, _ = select.select([sock], [], [], timeout)
|
|
|
|
if len(read_ready) > 0:
|
|
|
|
banner = sock.recv(BANNER_READ)
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
|
|
|
|
sock.close()
|
2015-11-30 16:56:20 +08:00
|
|
|
return True, banner
|
|
|
|
|
2015-09-29 22:58:06 +08:00
|
|
|
|
|
|
|
def check_port_udp(ip, port, timeout=DEFAULT_TIMEOUT):
|
|
|
|
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
|
|
|
sock.settimeout(timeout)
|
|
|
|
|
|
|
|
data = None
|
|
|
|
is_open = False
|
|
|
|
|
|
|
|
try:
|
|
|
|
sock.sendto("-", (ip, port))
|
2016-08-20 22:58:59 +08:00
|
|
|
data, _ = sock.recvfrom(BANNER_READ)
|
2015-09-29 22:58:06 +08:00
|
|
|
is_open = True
|
|
|
|
except:
|
|
|
|
pass
|
|
|
|
sock.close()
|
|
|
|
|
2015-11-30 16:56:20 +08:00
|
|
|
return is_open, data
|