使用Python的Pyside和Scapy写的嗅探器原型,拥有基本框架,但是功能并不十分完善,供参考。
1 import sys 2 import time 3 import binascii 4 from PySide.QtCore import * 5 from PySide.QtGui import * 6 from scapy.all import * 7 8 # Every Qt application must have one and only one QApplication object; 9 # it receives the command line arguments passed to the script, as they 10 # can be used to customize the application's appearance and behavior 11 qt_app = QApplication(sys.argv) 12 global_pkt_list = [] 13 14 # Try to redirect hexdump()'s output, but failed!Why? T_T 15 class redirect_output: 16 def __init__(self): 17 self.str = '' 18 def write(self, s): 19 self.str += s 20 def show(self): 21 return self.str 22 23 class Sniffer(QThread): 24 pkt_arrive = Signal(str) 25 bGo = True 26 filter = None 27 iface = 'eth0' 28 29 def __init__(self, parent=None): 30 QThread.__init__(self, parent) 31 # self.pkt_arrive.connect(OnPktArrive) 32 33 def run(self): 34 # self.emit(SIGNAL("pkt_arrive(str)"), "pkt") 35 while (self.bGo): 36 p = sniff(count=1, filter = self.filter) 37 global_pkt_list.append(p[0]) 38 self.pkt_arrive.emit((p[0].summary())) 39 40 def go(self): 41 self.bGo = True 42 self.start() 43 44 def stop(self): 45 print 'Sniffer got exit message' 46 self.bGo = False 47 48 class PktListItem(QListWidgetItem): 49 def __init__(self, pkt=None, num=None): 50 QListWidgetItem.__init__(self) 51 self.pkt = pkt 52 self.num = num 53 54 class MainWindow(QWidget): 55 ''' An example of PySide absolute positioning; the main window 56 inherits from QWidget, a convenient widget for an empty window. ''' 57 number = 0 58 def __init__(self): 59 QWidget.__init__(self) 60 self.setWindowTitle('J_Sniffer') 61 self.setMinimumSize(800, 500) 62 63 # set layout 64 self.main_layout = QVBoxLayout() 65 # edit and btn 66 self.layout1 = QHBoxLayout() 67 68 self.Label_Iface = QLabel("Iface", self) 69 self.layout1.addWidget(self.Label_Iface) 70 self.TextBox_Iface = QLineEdit(self) 71 self.TextBox_Iface.setPlaceholderText("Choose network interface") 72 self.layout1.addWidget(self.TextBox_Iface) 73 74 self.Label_Fliter = QLabel("Filter", self) 75 self.layout1.addWidget(self.Label_Fliter) 76 self.TextBox_Filter = QLineEdit(self) 77 self.layout1.addWidget(self.TextBox_Filter) 78 79 self.layout1.addStretch(1) 80 self.Btn_Start = QPushButton("&Start", self) 81 self.layout1.addWidget(self.Btn_Start) 82 83 self.main_layout.addLayout(self.layout1) 84 85 # List to show packets 86 self.List_Pkt = QListWidget(self) 87 self.main_layout.addWidget(self.List_Pkt) 88 89 # Tree to see pkt's detail 90 self.Tree = QTreeWidget(self) 91 self.main_layout.addWidget(self.Tree) 92 self.Tree.setColumnCount(2) 93 self.Tree.setHeaderLabels(['Key', 'Value']) 94 95 self.setLayout(self.main_layout) 96 97 # create signal and sniff thread 98 self.thread = Sniffer() 99 self.connect(self.Btn_Start, SIGNAL("clicked()"), self.Sniff) 100 # self.connect(self.thread, SIGNAL("pkt_arrive(str)"), self.OnPktArrive) Connot work! 101 self.thread.pkt_arrive.connect(self.OnPktArrive) 102 self.List_Pkt.currentItemChanged.connect(self.On_ItemChanged) 103 104 @Slot(str) 105 def OnPktArrive(self, pkt): 106 print 'received pkt arrive signal' 107 108 #p = Ether(pkt) #only Ethernet now, 802.11 may be crash! 109 item = PktListItem(num = self.number) 110 item.setText(str(self.number) + ' ' + pkt) 111 self.List_Pkt.addItem(item) 112 self.number += 1 113 114 @Slot() 115 def Sniff(self): 116 print self.Btn_Start.text() 117 if self.Btn_Start.text() == '&Start': 118 self.Btn_Start.setText("&Stop") 119 self.thread.filter = self.TextBox_Filter.text() 120 self.thread.iface = self.TextBox_Iface.text() 121 self.thread.go() 122 else: 123 self.Btn_Start.setText("&Start") 124 self.thread.stop() 125 126 def On_ItemChanged(self, curr, prev): 127 print curr.num 128 self.Tree.clear() 129 p = global_pkt_list[curr.num] 130 root1 = QTreeWidgetItem(self.Tree) 131 if (p.haslayer(Ether)): 132 root1.setText(0, 'Ethernet:') 133 child1_1 = QTreeWidgetItem(root1) 134 child1_1.setText(0, 'dst') 135 child1_1.setText(1, p.dst) 136 child1_2 = QTreeWidgetItem(root1) 137 child1_2.setText(0, 'src') 138 child1_2.setText(1, p.src) 139 child1_3 = QTreeWidgetItem(root1) 140 child1_3.setText(0, 'type') 141 child1_3.setText(1, hex(p.type)) 142 p = p.getlayer(1) 143 if (p.haslayer(IP)): 144 self._SetIPTree(p) 145 p = p.getlayer(1) 146 if (p.haslayer(ICMP)): 147 self._SetICMPTree(p) 148 elif (p.haslayer(TCP)): 149 pass 150 else: 151 pass 152 elif (p.haslayer(IPv6)): 153 pass 154 else: 155 root1.setText(0, 'Not Ethernet') 156 root1.setText(1, hexdump(p)) 157 158 def _SetIPTree(self, p): 159 root2 = QTreeWidgetItem(self.Tree) 160 root2.setText(0, 'IPv4') 161 child2_1 = QTreeWidgetItem(root2) 162 child2_1.setText(0, 'Version') 163 child2_1.setText(1, str(p.version)) 164 child2_2 = QTreeWidgetItem(root2) 165 child2_2.setText(0, 'ihl(Header Length)') 166 child2_2.setText(1, str(p.ihl)) 167 child2_3 = QTreeWidgetItem(root2) 168 child2_3.setText(0, 'tos') 169 child2_3.setText(1, str(p.tos)) 170 child2_4 = QTreeWidgetItem(root2) 171 child2_4.setText(0, 'len') 172 child2_4.setText(1, str(p.len)) 173 child2_5 = QTreeWidgetItem(root2) 174 child2_5.setText(0, 'id') 175 child2_5.setText(1, str(p.id)) 176 child2_6 = QTreeWidgetItem(root2) 177 child2_6.setText(0, 'flags') 178 child2_6.setText(1, str(p.flags)) 179 child2_7 = QTreeWidgetItem(root2) 180 child2_7.setText(0, 'frag') 181 child2_7.setText(1, str(p.frag)) 182 child2_8 = QTreeWidgetItem(root2) 183 child2_8.setText(0, 'TTL') 184 child2_8.setText(1, str(p.ttl)) 185 child2_9 = QTreeWidgetItem(root2) 186 child2_9.setText(0, 'protocol') 187 child2_9.setText(1, str(p.proto)) 188 child2_10 = QTreeWidgetItem(root2) 189 child2_10.setText(0, 'checksum') 190 child2_10.setText(1, str(p.chksum)) 191 child2_11 = QTreeWidgetItem(root2) 192 child2_11.setText(0, 'src') 193 child2_11.setText(1, str(p.src)) 194 child2_12 = QTreeWidgetItem(root2) 195 child2_12.setText(0, 'dst') 196 child2_12.setText(1, str(p.dst)) 197 198 def _SetICMPTree(self, p): 199 root3 = QTreeWidgetItem(self.Tree) 200 root3.setText(0, 'ICMP') 201 child3_1 = QTreeWidgetItem(root3) 202 child3_1.setText(0, 'Type') 203 if (p.type == 8): 204 child3_1.setText(1, 'echo request') 205 elif (p.type == 0): 206 child3_1.setText(1, 'echo reply') 207 else: 208 child3_1.setText(1, str(p.type)) 209 child3_2 = QTreeWidgetItem(root3) 210 child3_2.setText(0, 'Code') 211 child3_2.setText(1, str(p.code)) 212 child3_3 = QTreeWidgetItem(root3) 213 child3_3.setText(0, 'Checksum') 214 child3_3.setText(1, str(p.chksum)) 215 child3_4 = QTreeWidgetItem(root3) 216 child3_4.setText(0, 'ID') 217 child3_4.setText(1, str(p.id)) 218 child3_5 = QTreeWidgetItem(root3) 219 child3_5.setText(0, 'Sequence number') 220 child3_5.setText(1, str(p.seq)) 221 child3_6 = QTreeWidgetItem(root3) 222 child3_6.setText(0, 'Data') 223 child3_6.setText(1, binascii.b2a_hex(str(p.load))) 224 225 def run(self): 226 self.show() 227 228 if __name__ == '__main__': 229 # Create an instance of the application window and run it 230 win = MainWindow() 231 win.run() 232 qt_app.exec_()