2015-04-16 5 views
-1

Я пытаюсь закодировать сниффер пакетов с использованием Python и scapy и реализовать GUI с помощью Tkinter. Кажется, что все работает нормально, за исключением кнопки «Выход». Я использую код:Кнопки Tkinter не работают

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() 

Однако, когда я нажимаю на кнопку Quit, ничего не происходит. У меня нет анимации нажатия кнопки, и у меня нет закрытия программы. Что мне нужно изменить?

Сокращенная версия кода выглядит:

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

На какой платформе вы используете это на? –

+0

Linux Запуск этого на Ubuntu прямо сейчас. Также я очень новичок в Python, поэтому мой код беспорядок. Но если вы согласны, я могу показать это вам, если вы можете мне помочь. –

+0

Пожалуйста, прочитайте http://stackoverflow.com/help/mcve –

ответ

1

Вы используете лямбда для передачи переменной main_win в свою функцию, но тогда вы ссылаетесь только на функцию вместо того, чтобы позволить лямбда фактически называть ее.
Использование:

Button(..., command=lambda: exitClick(main_win)) 
+0

Я просто попробовал это. Не работает. Я думаю, что проблема заключается в том, что кнопка не может быть нажата в первую очередь. Обычно, когда вы нажимаете на кнопку Tkinter, она становится немного подавленной. Это не происходит в моей программе. Я не могу навести указатель мыши или щелкнуть по нему. –

+0

Хорошо, из вашего вопроса, который на самом деле мне не стал ясным, потому что способ, которым вы использовали лямбду, действительно не приведет к тому, что ничего не произойдет, когда вы нажмете кнопку. Тогда вам придется опубликовать пример кода, который демонстрирует проблему, потому что из кода, который вы опубликовали, нет ничего, что могло бы вызвать такое поведение. Пожалуйста, прочитайте ссылку, которую Брайан Оукли рассказал о том, как сделать правильный пример. – fhdrsdg

+0

Итак, я сократил дополнительный код, который не имел никакого отношения к проблеме, и довел его до этого. Надеюсь, что это лучший пример. –

Смежные вопросы