1 /* address_editor_frame.cpp
2 *
3 * Wireshark - Network traffic analyzer
4 * By Gerald Combs <gerald@wireshark.org>
5 * Copyright 1998 Gerald Combs
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "config.h"
11
12 #include <glib.h>
13
14 #include "file.h"
15 #include "frame_tvbuff.h"
16
17 #include "epan/addr_resolv.h"
18 #include "epan/epan_dissect.h"
19 #include "epan/frame_data.h"
20
21 #include "address_editor_frame.h"
22 #include <ui_address_editor_frame.h>
23
24 #include <QPushButton>
25 #include <QKeyEvent>
26
27 #include <ui/qt/utils/qt_ui_utils.h>
28 #include <ui/qt/wireshark_application.h>
29
30 // To do:
31 // - Fill in currently resolved address.
32
AddressEditorFrame(QWidget * parent)33 AddressEditorFrame::AddressEditorFrame(QWidget *parent) :
34 AccordionFrame(parent),
35 ui(new Ui::AddressEditorFrame),
36 cap_file_(NULL)
37 {
38 ui->setupUi(this);
39
40 #ifdef Q_OS_MAC
41 foreach (QWidget *w, findChildren<QWidget *>()) {
42 w->setAttribute(Qt::WA_MacSmallSize, true);
43 }
44 #endif
45 }
46
~AddressEditorFrame()47 AddressEditorFrame::~AddressEditorFrame()
48 {
49 delete ui;
50 }
51
editAddresses(CaptureFile & cf,int column)52 void AddressEditorFrame::editAddresses(CaptureFile &cf, int column)
53 {
54 cap_file_ = cf.capFile();
55
56 if (!cap_file_->current_frame) {
57 on_buttonBox_rejected();
58 return;
59 }
60
61 if (!cf_read_current_record(cap_file_)) {
62 on_buttonBox_rejected();
63 return; // error reading the frame
64 }
65
66 epan_dissect_t edt;
67 QStringList addresses;
68
69 ui->addressComboBox->clear();
70
71 epan_dissect_init(&edt, cap_file_->epan, FALSE, FALSE);
72 col_custom_prime_edt(&edt, &cap_file_->cinfo);
73
74 epan_dissect_run(&edt, cap_file_->cd_t, &cap_file_->rec,
75 frame_tvbuff_new_buffer(&cap_file_->provider, cap_file_->current_frame, &cap_file_->buf),
76 cap_file_->current_frame, &cap_file_->cinfo);
77 epan_dissect_fill_in_columns(&edt, TRUE, TRUE);
78
79 /* First check selected column */
80 if (isAddressColumn(&cap_file_->cinfo, column)) {
81 addresses << cap_file_->cinfo.col_expr.col_expr_val[column];
82 }
83
84 for (int col = 0; col < cap_file_->cinfo.num_cols; col++) {
85 /* Then check all columns except the selected */
86 if ((col != column) && (isAddressColumn(&cap_file_->cinfo, col))) {
87 addresses << cap_file_->cinfo.col_expr.col_expr_val[col];
88 }
89 }
90
91 epan_dissect_cleanup(&edt);
92
93 displayPreviousUserDefinedHostname();
94
95 ui->addressComboBox->addItems(addresses);
96 ui->nameLineEdit->setFocus();
97 updateWidgets();
98 }
99
showEvent(QShowEvent * event)100 void AddressEditorFrame::showEvent(QShowEvent *event)
101 {
102 ui->nameLineEdit->setFocus();
103 ui->nameLineEdit->selectAll();
104
105 AccordionFrame::showEvent(event);
106 }
107
keyPressEvent(QKeyEvent * event)108 void AddressEditorFrame::keyPressEvent(QKeyEvent *event)
109 {
110 if (event->modifiers() == Qt::NoModifier) {
111 if (event->key() == Qt::Key_Escape) {
112 on_buttonBox_rejected();
113 } else if (event->key() == Qt::Key_Enter || event->key() == Qt::Key_Return) {
114 if (ui->buttonBox->button(QDialogButtonBox::Ok)->isEnabled()) {
115 on_buttonBox_accepted();
116 }
117 }
118 }
119
120 AccordionFrame::keyPressEvent(event);
121 }
122
displayPreviousUserDefinedHostname()123 void AddressEditorFrame::displayPreviousUserDefinedHostname()
124 {
125 QString addr = ui->addressComboBox->currentText();
126 resolved_name_t* previous_entry = get_edited_resolved_name(addr.toUtf8().constData());
127 if (previous_entry)
128 {
129 ui->nameLineEdit->setText(previous_entry->name);
130 }
131 else
132 {
133 ui->nameLineEdit->setText("");
134 }
135 }
136
updateWidgets()137 void AddressEditorFrame::updateWidgets()
138 {
139 bool ok_enable = false;
140 if (ui->addressComboBox->count() > 0) {
141 ok_enable = true;
142 }
143
144 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(ok_enable);
145 }
146
on_nameResolutionPreferencesToolButton_clicked()147 void AddressEditorFrame::on_nameResolutionPreferencesToolButton_clicked()
148 {
149 on_buttonBox_rejected();
150 emit showNameResolutionPreferences("nameres");
151 }
152
on_addressComboBox_currentIndexChanged(const QString &)153 void AddressEditorFrame::on_addressComboBox_currentIndexChanged(const QString &)
154 {
155 displayPreviousUserDefinedHostname();
156 updateWidgets();
157 }
158
on_nameLineEdit_textEdited(const QString &)159 void AddressEditorFrame::on_nameLineEdit_textEdited(const QString &)
160 {
161 updateWidgets();
162 }
163
on_buttonBox_accepted()164 void AddressEditorFrame::on_buttonBox_accepted()
165 {
166 if (ui->addressComboBox->count() < 1) {
167 return;
168 }
169 QString addr = ui->addressComboBox->currentText();
170 QString name = ui->nameLineEdit->text();
171 if (!cf_add_ip_name_from_string(cap_file_, addr.toUtf8().constData(), name.toUtf8().constData())) {
172 QString error_msg = tr("Can't assign %1 to %2.").arg(name).arg(addr);
173 wsApp->pushStatus(WiresharkApplication::TemporaryStatus, error_msg);
174 ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
175 return;
176 }
177 on_buttonBox_rejected();
178 emit redissectPackets();
179 }
180
on_buttonBox_rejected()181 void AddressEditorFrame::on_buttonBox_rejected()
182 {
183 ui->addressComboBox->clear();
184 ui->nameLineEdit->clear();
185 animatedHide();
186 }
187
isAddressColumn(epan_column_info * cinfo,int column)188 bool AddressEditorFrame::isAddressColumn(epan_column_info *cinfo, int column)
189 {
190 if (!cinfo || column < 0 || column >= cinfo->num_cols) return false;
191
192 if (((cinfo->columns[column].col_fmt == COL_DEF_SRC) ||
193 (cinfo->columns[column].col_fmt == COL_RES_SRC) ||
194 (cinfo->columns[column].col_fmt == COL_DEF_DST) ||
195 (cinfo->columns[column].col_fmt == COL_RES_DST)) &&
196 strlen(cinfo->col_expr.col_expr_val[column]))
197 {
198 return true;
199 }
200
201 return false;
202 }
203