A Discrete-Event Network Simulator
API
Loading...
Searching...
No Matches
show_last_packets.py
Go to the documentation of this file.
1from gi.repository import GObject, Gtk
2
3try:
4 from ns import ns
5except ModuleNotFoundError:
6 raise SystemExit(
7 "Error: ns3 Python module not found;"
8 " Python bindings may not be enabled"
9 " or your PYTHONPATH might not be properly configured"
10 )
11
12try:
13 from ns3.visualizer.base import InformationWindow
14except ModuleNotFoundError:
15 from visualizer.base import InformationWindow
16
17from kiwi.ui.objectlist import Column, ObjectList
18
19
20## ShowLastPackets class
22 ## @var win
23 # window
24 ## @var visualizer
25 # visualizer
26 ## @var viz_node
27 # visualizer node
28 ## @var node
29 # the node
30 ## @var tx_list
31 # packet transmit list
32 ## @var rx_list
33 # packet receive list
34 ## @var drop_list
35 # packet drop list
36 ## @var packet_capture_options
37 # packet capture options
38 ## @var packet_filter_widget
39 # packet filter widget
40 ## @var packet_filter_list
41 # list of TypeIdConfig instances
42 ## @var op_AND_button
43 # AND button
44 ## @var op_OR_button
45 # OR button
46 ## @var _response_cb
47 # _response_cb function
48
49 class PacketList(Gtk.ScrolledWindow):
50 """
51 PacketList class
52 """
53
54 ## @var table_model
55 # table model
56 ## @var COLUMN_TIME
57 # COLUMN_TIME constant
58 ## @var COLUMN_INTERFACE
59 # COLUMN_INTERFACE constant
60 ## @var COLUMN_SIZE
61 # COLUMN_SIZE constant
62 ## @var COLUMN_CONTENTS
63 # COLUMN_CONTENTS constant
64 (
65 COLUMN_TIME,
66 COLUMN_INTERFACE,
67 COLUMN_SIZE,
68 COLUMN_CONTENTS,
69 ) = range(4)
70
71 def __init__(self):
72 """
73 Initializer
74 @param self this object
75 """
77 self.set_properties(
78 hscrollbar_policy=Gtk.PolicyType.AUTOMATIC,
79 vscrollbar_policy=Gtk.PolicyType.AUTOMATIC,
80 )
81 self.table_model = Gtk.ListStore(*([str] * 4))
82 treeview = Gtk.TreeView(self.table_model)
83 treeview.show()
84 self.add(treeview)
85
86 def add_column(descr, colid):
87 column = Gtk.TreeViewColumn(descr, Gtk.CellRendererText(), text=colid)
88 treeview.append_column(column)
89
90 add_column("Time", self.COLUMN_TIME)
91 add_column("Interface", self.COLUMN_INTERFACE)
92 add_column("Size", self.COLUMN_SIZE)
93 add_column("Contents", self.COLUMN_CONTENTS)
94
95 def update(self, node, packet_list):
96 """!
97 Update function
98 @param self this object
99 @param node the node
100 @param packet_list packet list
101 @return none
102 """
103 self.table_model.clear()
104 for sample in packet_list:
105 tree_iter = self.table_model.append()
106 if sample.device is None:
107 interface_name = "(unknown)"
108 else:
109 interface_name = ns.Names.FindName(sample.device)
110 if not interface_name:
111 interface_name = "(interface %i)" % sample.device.GetIfIndex()
112 self.table_model.set(
113 tree_iter,
114 self.COLUMN_TIME,
115 str(sample.time.GetSeconds()),
116 self.COLUMN_INTERFACE,
117 interface_name,
118 self.COLUMN_SIZE,
119 str(sample.packet.GetSize()),
120 self.COLUMN_CONTENTS,
121 str(sample.packet),
122 )
123
124 def __init__(self, visualizer, node_index):
125 """!
126 Initializer
127 @param self this object
128 @param visualizer the visualizer object
129 @param node_index the node index
130 """
131 InformationWindow.__init__(self)
132 self.win = Gtk.Dialog(
133 parent=visualizer.window,
134 flags=Gtk.DialogFlags.DESTROY_WITH_PARENT,
135 buttons=("_Close", Gtk.ResponseType.CLOSE),
136 )
137 self.win.connect("response", self._response_cb_response_cb)
138 self.win.set_title("Last packets for node %i" % node_index)
139 self.visualizer = visualizer
140 self.viz_node = visualizer.get_node(node_index)
141 self.node = ns.NodeList.GetNode(node_index)
142
143 def smart_expand(expander, vbox):
144 if expander.get_expanded():
145 vbox.set_child_packing(
146 expander, expand=True, fill=True, padding=0, pack_type=Gtk.PACK_START
147 )
148 else:
149 vbox.set_child_packing(
150 expander, expand=False, fill=False, padding=0, pack_type=Gtk.PACK_START
151 )
152
153 main_hbox = Gtk.HBox(False, 4)
154 main_hbox.show()
155 main_vbox = Gtk.VBox(False, 4)
156 main_vbox.show()
157 self.win.vbox.add(main_hbox)
158 main_hbox.add(main_vbox)
159
160 self.tx_list = self.PacketList()
161 self.tx_list.show()
162 group = Gtk.Expander("Last transmitted packets")
163 group.show()
164 group.add(self.tx_list)
165 main_vbox.pack_start(group, expand=False, fill=False)
166 group.connect_after("activate", smart_expand, main_vbox)
167
168 self.rx_list = self.PacketList()
169 self.rx_list.show()
170 group = Gtk.Expander("Last received packets")
171 group.show()
172 group.add(self.rx_list)
173 main_vbox.pack_start(group, expand=False, fill=False)
174 group.connect_after("activate", smart_expand, main_vbox)
175
176 self.drop_list = self.PacketList()
177 self.drop_list.show()
178 group = Gtk.Expander("Last dropped packets")
179 group.show()
180 group.add(self.drop_list)
181 main_vbox.pack_start(group, expand=False, fill=False)
182 group.connect_after("activate", smart_expand, main_vbox)
183
184 # Packet Filter
185
186 # - options
187 self.packet_capture_options = ns.PyViz.PacketCaptureOptions()
188 self.packet_capture_options.numLastPackets = 100
189
190 packet_filter_vbox = Gtk.VBox(False, 4)
191 packet_filter_vbox.show()
192 main_hbox.add(packet_filter_vbox)
193
194 sel_buttons_box = Gtk.HButtonBox()
195 sel_buttons_box.show()
196 packet_filter_vbox.pack_start(sel_buttons_box, False, False, 4)
197 select_all_button = GObject.new(Gtk.Button, label="Sel. All", visible=True)
198 select_none_button = GObject.new(Gtk.Button, label="Sel. None", visible=True)
199 sel_buttons_box.add(select_all_button)
200 sel_buttons_box.add(select_none_button)
201
202 self.packet_filter_widget = ObjectList(
203 [
204 Column("selected", title="Sel.", data_type=bool, editable=True),
205 Column("name", title="Header"),
206 ],
207 sortable=True,
208 )
209 self.packet_filter_widget.show()
210 packet_filter_vbox.pack_start(self.packet_filter_widget, True, True, 4)
211
212 class TypeIdConfig(object):
213 __slots__ = ["name", "selected", "typeid"]
214
215 self.packet_filter_list = [] # list of TypeIdConfig instances
216
217 Header = ns.TypeId.LookupByName("ns3::Header")
218 Trailer = ns.TypeId.LookupByName("ns3::Trailer")
219 for typeid_i in range(ns.TypeId.GetRegisteredN()):
220 typeid = ns.TypeId.GetRegistered(typeid_i)
221 # check if this is a header or trailer subtype
222 typeid_tmp = typeid
223 type_is_good = False
224 while 1:
225 if typeid_tmp == Header or typeid_tmp == Trailer:
226 type_is_good = True
227 break
228 if typeid_tmp.HasParent():
229 typeid_tmp = typeid_tmp.GetParent()
230 else:
231 break
232 if not type_is_good:
233 continue
234 if typeid in [Header, Trailer]:
235 continue
236 c = TypeIdConfig()
237 c.selected = True
238 c.name = typeid.GetName()
239 c.typeid = typeid
240 self.packet_filter_list.append(c)
241 self.packet_filter_widget.add_list(self.packet_filter_list)
242
243 def update_capture_options():
244 if self.op_AND_button.props.active:
245 self.packet_capture_options.mode = ns.PyViz.PACKET_CAPTURE_FILTER_HEADERS_AND
246 else:
247 self.packet_capture_options.mode = ns.PyViz.PACKET_CAPTURE_FILTER_HEADERS_OR
248 self.packet_capture_options.numLastPackets = 100
249 self.packet_capture_options.headers = [
250 c.typeid for c in self.packet_filter_list if c.selected
251 ]
252 self.visualizer.simulation.lock.acquire()
253 try:
254 self.visualizer.simulation.sim_helper.SetPacketCaptureOptions(
255 self.node.GetId(), self.packet_capture_options
256 )
257 finally:
258 self.visualizer.simulation.lock.release()
259
260 def sel_all_cb(bt):
261 for c in self.packet_filter_list:
262 c.selected = True
263 self.packet_filter_widget.refresh()
264 update_capture_options()
265
266 def sel_none_cb(bt):
267 for c in self.packet_filter_list:
268 c.selected = False
269 self.packet_filter_widget.refresh()
270 update_capture_options()
271
272 select_all_button.connect("clicked", sel_all_cb)
273 select_none_button.connect("clicked", sel_none_cb)
274
275 op_buttons_box = Gtk.HButtonBox()
276 op_buttons_box.show()
277 packet_filter_vbox.pack_start(op_buttons_box, False, False, 4)
278 self.op_AND_button = GObject.new(Gtk.RadioButton, label="AND", visible=True)
279 self.op_OR_button = GObject.new(
280 Gtk.RadioButton, label="OR", visible=True, group=self.op_AND_button
281 )
282 op_buttons_box.add(self.op_AND_button)
283 op_buttons_box.add(self.op_OR_button)
284 self.op_OR_button.props.active = True
285
286 self.op_AND_button.connect("toggled", lambda b: update_capture_options())
287
288 def cell_edited(l, obj, attribute):
289 update_capture_options()
290
291 self.packet_filter_widget.connect("cell-edited", cell_edited)
292
293 update_capture_options()
294
295 self.visualizer.add_information_window(self)
296 self.win.set_default_size(600, 300)
297 self.win.show()
298
299 def _response_cb(self, win, response):
300 """!
301 Response callback function
302 @param self this object
303 @param win the window
304 @param response the response
305 @return none
306 """
307 self.win.destroy()
308 self.visualizer.remove_information_window(self)
309
310 def update(self):
311 """!
312 Update function
313 @param self this object
314 @return none
315 """
316 last_packets = self.visualizer.simulation.sim_helper.GetLastPackets(self.node.GetId())
317
318 self.tx_list.update(self.node, last_packets.lastTransmittedPackets)
319 self.rx_list.update(self.node, last_packets.lastReceivedPackets)
320 self.drop_list.update(self.node, last_packets.lastDroppedPackets)
321
322
323def populate_node_menu(viz, node, menu):
324 menu_item = Gtk.MenuItem("Show Last Packets")
325 menu_item.show()
326
327 def _show_it(dummy_menu_item):
328 ShowLastPackets(viz, node.node_index)
329
330 menu_item.connect("activate", _show_it)
331 menu.add(menu_item)
332
333
334def register(viz):
335 viz.connect("populate-node-menu", populate_node_menu)
update(self, node, packet_list)
Update function.
packet_capture_options
packet capture options
_response_cb(self, win, response)
Response callback function.
__init__(self, visualizer, node_index)
Initializer.
packet_filter_list
list of TypeIdConfig instances
InformationWindow class.
Definition base.py:28
populate_node_menu(viz, node, menu)