我尝试使用Python和scapy编写数据包嗅探器,并使用Tkinter实现GUI。除了" Quit"以外,一切似乎都运转良好。按钮。我使用的代码是:
quitButton = Button(main_win,text="Quit", command=lambda:exitClick)
quitButton.pack(side="bottom")
函数exitClick()定义为:
def exitClick(main_win):
main_win.destroy()
main_win.quit()
sys.exit()
然而,当我点击退出按钮时,没有任何反应。我没有按钮动画,也没有关闭程序。我需要改变什么?
代码的删节版本如下:
import fcntl, easygui, logging
from Tkinter import *
logging.getLogger("scapy.runtime").setLevel(logging.ERROR)
from scapy.all import *
inc_txt_str = ""
out_txt_str = ""
def exitClick(main_win):
main_win.quit()
sys.exit()
main_win = Tk()
main_win.withdraw()
frame_incoming = Frame(main_win)
t = Text(frame_incoming, width=45, bg="black", fg="white")
t.pack(fill=BOTH, expand=YES, side="left")
s = Scrollbar(frame_incoming)
s.pack(side="right", fill="y")
s.config(command=t.yview)
t.config(yscrollcommand=s.set)
frame_incoming.pack(side="left")
frame_outgoing = Frame(main_win)
t1 = Text(frame_outgoing, width=45, bg="white", fg="black")
t1.pack(side="left", fill="both", expand=YES)
s1 = Scrollbar(frame_outgoing)
s1.pack(side="right", fill="y")
s1.config(command=t1.yview)
t1.config(yscrollcommand=s1.set)
frame_outgoing.pack(side="left")
border_buttons = Frame(main_win)
border_buttons.pack(side="bottom")
quitButton = Button(main_win,text="Quit", command=lambda:exitClick(main_win))
quitButton.pack(side="bottom")
parseButton = Button(main_win, text='Parse IP')
parseButton.pack(side="bottom")
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
class sniffPacket:
def processIPFrame(self, pkt_type, ip_header, payload):
fields = struct.unpack("!BBHHHBBHII", ip_header)
dummy_hdrlen = fields[0] & 0xf
iplen = fields[2]
ip_src = payload[12:16]
ip_dst = payload[16:20]
ip_frame = payload[0:iplen]
if pkt_type == socket.PACKET_OUTGOING:
if self.outgoingIP is not None:
self.outgoingIP(ip_src, ip_dst, ip_frame)
else:
if self.incomingIP is not None:
self.incomingIP(ip_src, ip_dst, ip_frame)
def __init__(self, interface_name, incomingIP, outgoingIP):
self.interface_name = interface_name
self.incomingIP = incomingIP
self.outgoingIP = outgoingIP
self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(ETH_P_ALL))
self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2 ** 30)
self.ins.bind((self.interface_name, ETH_P_ALL))
pkt, sa_ll = self.ins.recvfrom(MTU)
eth_header = struct.unpack("!6s6sH", pkt[0:14])
dummy_eth_protocol = socket.ntohs(eth_header[2])
ip_header = pkt[14:34]
payload = pkt[14:]
self.processIPFrame(sa_ll[2], ip_header, payload)
def getPacket(self):
pkt, sa_ll = self.ins.recvfrom(MTU)
eth_header = struct.unpack("!6s6sH", pkt[0:14])
dummy_eth_protocol = socket.ntohs(eth_header[2])
ip_header = pkt[14:34]
payload = pkt[14:]
self.processIPFrame(sa_ll[2], ip_header, payload)
main_win.after(500,getPacket())
def all_interfaces():
max_possible = 128
bytes = max_possible * 32
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
names = array.array('B', '\0' * bytes)
outbytes = struct.unpack('iL', fcntl.ioctl(
s.fileno(),
0x8912, # SIOCGIFCONF
struct.pack('iL', bytes, names.buffer_info()[0])))[0]
namestr = names.tostring()
lst = []
for i in range(0, outbytes, 40):
name = namestr[i:i + 16].split('\0', 1)[0]
ip = namestr[i + 20:i + 24]
lst.append((name, ip))
return lst
def format_ip(addr):
return str(ord(addr[0])) + '.' + \
str(ord(addr[1])) + '.' + \
str(ord(addr[2])) + '.' + \
str(ord(addr[3]))
def get_ip_address(ifname):
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
return socket.inet_ntoa(fcntl.ioctl(
s.fileno(),
0x8915, # SIOCGIFADDR
struct.pack('256s', ifname[:15]))[20:24])
def incoming_packet_callback(src, dst, frame_incoming):
global inc_txt_str
main_win.deiconify()
inc_txt_str += "Incoming from "
inc_txt_str += str(socket.inet_ntoa(src))
inc_txt_str += "\n"
t.insert(END, inc_txt_str)
t.see(END)
t.update_idletasks()
def outgoing_packet_callback(src, dst, frame_incoming):
global out_txt_str
main_win.deiconify()
out_txt_str += "Outgoing to "
out_txt_str += str(socket.inet_ntoa(dst))
out_txt_str += "\n"
t1.insert(END, out_txt_str)
t1.see(END)
t1.update_idletasks()
interface = "wlan0"
ip_s = sniffPacket(interface, incoming_packet_callback, outgoing_packet_callback)
#main_win.after(500,ip_s.getPacket)
main_win.mainloop()
我对Python非常陌生,我相信我已经犯了一些重大的概念错误,导致了这个问题。
答案 0 :(得分:1)
你使用lambda能够将main_win
变量传递给你的函数,但是你只引用函数而不是让lambda实际调用它。
使用:
Button(..., command=lambda: exitClick(main_win))