Анализатор пакетов Python для локальной сети
Как видно из названия, я делаю анализатор пакетов в Python 2.7(для совместимости должен быть 2.7).
Я получил требуемую функциональность, прослушивая весь входящий или исходящий трафик, использующий TCP, UDP или ICMP, с кодом следующим образом:
utils.py
это модуль с функциями, которые анализируют каждый вид пакета вместе с несколькими другими вспомогательными функциями, функции, которые создают сокет:
def socket_safe(*args):
# Sets up a socket using the specified args, taking care of any exceptions
# and returning the socket descriptor object
try:
sd = socket.socket(*args)
except error, msg:
print 'Error', msg[0], 'creating socket:', msg[0]
sys.exit()
return sd
def socket_universal():
# Uses the socket_safe function to set up a socket object that will capture
# any incoming or outgoing (including TCP, UDP and ICMP)
# 0x0003 is ETH_P_ALL
return socket_safe(socket.AF_PACKET , socket.SOCK_RAW , socket.ntohs(0x0003))
И основной файл таков:
from struct import *
from socket import *
from utils import *
eth_protocols = {'ip_protocol' : 8}
ip_protocols = {'tcp_protocol' : 6,
'icmp_protocol' : 1,
'udp_protocol' : 17}
# Create a socket descriptor object that will receive any type of packet.
# For details please see the function definition in utils.py
sd = socket_universal()
for _ in range(5):
print 'WAITING FOR PACKET...'
# Receive up to 65565 bytes of data from any available source
# as a tuple of the form (packet_contents, source_socket_info)
packet, \
source \
= sd.recvfrom(65565)
print 'PACKET RECEIVED : '
# Parse the destination and source MAC addresses and the protocol from the ethernet header.
# For details please see the function definition in utils.py
dest_mac, \
src_mac, \
eth_protocol \
= parse_ethernet_header(packet)
print '\tETHERNET HEADER : \n', \
'\t\tDestination MAC :', dest_mac, '\n', \
'\t\tSource MAC : ', src_mac, '\n', \
'\t\tEth. Protocol : ', eth_protocol
# Parse IP packets
if eth_protocol == eth_protocols['ip_protocol']:
# Parse all available information from the IP header of the packet.
# For details please see the function definition in utils.py
version, \
ihl, \
type_of_service, \
total_len, \
identification, \
ip_flags, \
offset, \
ttl, \
ip_protocol, \
ip_checksum, \
src_ip_addr, \
dest_ip_addr \
= parse_ip_header(packet)
print '\tIP HEADER : \n', \
'\t\tVersion : ', version, '\n', \
'\t\tIP Header Length : ', ihl, '\n', \
'\t\tType of Service : ', type_of_service, '\n', \
'\t\tTotal Length : ', total_len, '\n', \
'\t\tIdentification : ', identification, '\n', \
'\t\tFlags : ', ip_flags, '\n', \
'\t\tOffset : ', offset, '\n', \
'\t\tTime to Live : ', ttl , '\n', \
'\t\tIP Protocol : ', ip_protocol, '\n', \
'\t\tChecksum : ', ip_checksum, '\n', \
'\t\tSource Address : ', src_ip_addr, '\n', \
'\t\tDestination Address :', dest_ip_addr
# Parse TCP packets
if ip_protocol == ip_protocols['tcp_protocol']:
# Parse all available information from the TCP header of the packet.
# For details please see the function definition in utils.py
src_port, \
dest_port, \
seq_num, \
ack_num, \
data_offs, \
tcp_flags, \
window, \
tcp_checksum, \
urg_ptr, \
data \
= parse_tcp_header(packet, ihl)
print '\tTCP HEADER: \n', \
'\t\tSource Port : ', src_port, '\n', \
'\t\tDest Port : ', dest_port, '\n', \
'\t\tSequence Number : ', seq_num, '\n', \
'\t\tAcknowledgement : ', ack_num, '\n', \
'\t\tTCP header length :', data_offs, '\n', \
'\t\tFlags : ', tcp_flags, '\n', \
'\t\tWindow : ', window, '\n', \
'\t\tChecksum : ', tcp_checksum, '\n', \
'\t\tUrgen Pointer : ', urg_ptr, '\n', \
'\t\tData : ', data
# Parse ICMP packets
elif ip_protocol == ip_protocols['icmp_protocol']:
# Parse all available information from the ICMP header of the packet.
# For details please see the function definition in utils.py
icmp_type, \
code, \
icmp_checksum, \
data \
= dataparse_icmp_header(packet, ihl)
print '\tIMCP HEADER : \n', \
'\t\tType : ', icmp_type, '\n', \
'\t\tCode : ', code, '\n', \
'\t\tChecksum :', icmp_checksum, '\n', \
'\t\tData : ', data
# Parse UDP packets
elif ip_protocol == ip_protocols['udp_protocols']:
src_port, \
dest_port, \
length, \
udp_checksum, \
data \
= parse_udp_header(packet, ihl)
print '\tUDP HEADER : \n', \
'\t\tSource Port :', src_port, '\n', \
'\t\tDest Port : ', dest_port, '\n', \
'\t\tLength : ', length, '\n', \
'\t\tChecksum : ', udp_checksum, '\n', \
'\t\tData : ', data
else:
print '\tNOT A TCP, ICMP OR UDP PACKAGE. SKIPPING...'
print '\tEND OF PACKET.\n'
Теперь, что мне нужно сделать, это позволяет только прослушивать пакеты в локальной сети.
Если бы мне нужны были только пакеты между определенными машинами, я думаю, что это можно было бы решить довольно быстро, используя список IP-адресов или MAC-адресов нужных машин и несколько if
s, но я не уверен, как именно я должен различать, какие пакеты представляют трафик в локальной сети.
Я думаю, что я должен использовать source
часть sd.recvfrom(65565)
как я увидел название, которое может быть newtork, но документация по этому вопросу... просто отсутствует, по крайней мере, в официальной документации по python, нет ссылок на справочные страницы или что-то в этом роде.
Нижний вопрос: как мне ограничить "сниффинг" только локальной сетью?
Заранее спасибо!