xref: /netbsd-src/external/bsd/wpa/dist/wpa_supplicant/wpa_gui-qt4/addinterface.cpp (revision 36ebd06e5ab61115eab7acca17a2350fc8222071)
18dbcf02cSchristos /*
28dbcf02cSchristos  * wpa_gui - AddInterface class
38dbcf02cSchristos  * Copyright (c) 2008, Jouni Malinen <j@w1.fi>
48dbcf02cSchristos  *
5e604d861Schristos  * This software may be distributed under the terms of the BSD license.
6e604d861Schristos  * See README for more details.
78dbcf02cSchristos  */
88dbcf02cSchristos 
98dbcf02cSchristos #include <cstdio>
108dbcf02cSchristos #include "common/wpa_ctrl.h"
118dbcf02cSchristos 
128dbcf02cSchristos #include <QMessageBox>
138dbcf02cSchristos 
148dbcf02cSchristos #include "wpagui.h"
158dbcf02cSchristos #include "addinterface.h"
168dbcf02cSchristos 
178dbcf02cSchristos #ifdef CONFIG_NATIVE_WINDOWS
188dbcf02cSchristos #include <windows.h>
198dbcf02cSchristos 
208dbcf02cSchristos #ifndef WPA_KEY_ROOT
218dbcf02cSchristos #define WPA_KEY_ROOT HKEY_LOCAL_MACHINE
228dbcf02cSchristos #endif
238dbcf02cSchristos #ifndef WPA_KEY_PREFIX
248dbcf02cSchristos #define WPA_KEY_PREFIX TEXT("SOFTWARE\\wpa_supplicant")
258dbcf02cSchristos #endif
268dbcf02cSchristos #endif /* CONFIG_NATIVE_WINDOWS */
278dbcf02cSchristos 
288dbcf02cSchristos 
AddInterface(WpaGui * _wpagui,QWidget * parent)298dbcf02cSchristos AddInterface::AddInterface(WpaGui *_wpagui, QWidget *parent)
308dbcf02cSchristos 	: QDialog(parent), wpagui(_wpagui)
318dbcf02cSchristos {
328dbcf02cSchristos 	setWindowTitle(tr("Select network interface to add"));
338dbcf02cSchristos 	resize(400, 200);
348dbcf02cSchristos 	vboxLayout = new QVBoxLayout(this);
358dbcf02cSchristos 
368dbcf02cSchristos 	interfaceWidget = new QTreeWidget(this);
378dbcf02cSchristos 	interfaceWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
388dbcf02cSchristos 	interfaceWidget->setUniformRowHeights(true);
398dbcf02cSchristos 	interfaceWidget->setSortingEnabled(true);
408dbcf02cSchristos 	interfaceWidget->setColumnCount(3);
418dbcf02cSchristos 	interfaceWidget->headerItem()->setText(0, tr("driver"));
428dbcf02cSchristos 	interfaceWidget->headerItem()->setText(1, tr("interface"));
438dbcf02cSchristos 	interfaceWidget->headerItem()->setText(2, tr("description"));
44*36ebd06eSchristos 	interfaceWidget->setItemsExpandable(false);
45*36ebd06eSchristos 	interfaceWidget->setRootIsDecorated(false);
468dbcf02cSchristos 	vboxLayout->addWidget(interfaceWidget);
478dbcf02cSchristos 
488dbcf02cSchristos 	connect(interfaceWidget,
498dbcf02cSchristos 		SIGNAL(itemActivated(QTreeWidgetItem *, int)), this,
508dbcf02cSchristos 		SLOT(interfaceSelected(QTreeWidgetItem *)));
518dbcf02cSchristos 
528dbcf02cSchristos 	addInterfaces();
538dbcf02cSchristos }
548dbcf02cSchristos 
558dbcf02cSchristos 
addInterfaces()568dbcf02cSchristos void AddInterface::addInterfaces()
578dbcf02cSchristos {
588dbcf02cSchristos #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
598dbcf02cSchristos 	struct wpa_ctrl *ctrl;
608dbcf02cSchristos 	int ret;
618dbcf02cSchristos 	char buf[2048];
628dbcf02cSchristos 	size_t len;
638dbcf02cSchristos 
648dbcf02cSchristos 	ctrl = wpa_ctrl_open(NULL);
658dbcf02cSchristos 	if (ctrl == NULL)
668dbcf02cSchristos 		return;
678dbcf02cSchristos 
688dbcf02cSchristos 	len = sizeof(buf) - 1;
698dbcf02cSchristos 	ret = wpa_ctrl_request(ctrl, "INTERFACE_LIST", 14, buf, &len, NULL);
708dbcf02cSchristos 	if (ret < 0) {
718dbcf02cSchristos 		wpa_ctrl_close(ctrl);
728dbcf02cSchristos 		return;
738dbcf02cSchristos 	}
748dbcf02cSchristos 	buf[len] = '\0';
758dbcf02cSchristos 
768dbcf02cSchristos 	wpa_ctrl_close(ctrl);
778dbcf02cSchristos 
788dbcf02cSchristos 	QString ifaces(buf);
798dbcf02cSchristos 	QStringList lines = ifaces.split(QRegExp("\\n"));
808dbcf02cSchristos 	for (QStringList::Iterator it = lines.begin();
818dbcf02cSchristos 	     it != lines.end(); it++) {
828dbcf02cSchristos 		QStringList arg = (*it).split(QChar('\t'));
838dbcf02cSchristos 		if (arg.size() < 3)
848dbcf02cSchristos 			continue;
858dbcf02cSchristos 		QTreeWidgetItem *item = new QTreeWidgetItem(interfaceWidget);
868dbcf02cSchristos 		if (!item)
878dbcf02cSchristos 			break;
888dbcf02cSchristos 
898dbcf02cSchristos 		item->setText(0, arg[0]);
908dbcf02cSchristos 		item->setText(1, arg[1]);
918dbcf02cSchristos 		item->setText(2, arg[2]);
928dbcf02cSchristos 	}
938dbcf02cSchristos 
948dbcf02cSchristos 	interfaceWidget->resizeColumnToContents(0);
958dbcf02cSchristos 	interfaceWidget->resizeColumnToContents(1);
968dbcf02cSchristos 	interfaceWidget->resizeColumnToContents(2);
978dbcf02cSchristos #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
988dbcf02cSchristos }
998dbcf02cSchristos 
1008dbcf02cSchristos 
1018dbcf02cSchristos #ifdef CONFIG_NATIVE_WINDOWS
addRegistryInterface(const QString & ifname)1028dbcf02cSchristos bool AddInterface::addRegistryInterface(const QString &ifname)
1038dbcf02cSchristos {
1048dbcf02cSchristos 	HKEY hk, ihk;
1058dbcf02cSchristos 	LONG ret;
1068dbcf02cSchristos 	int id, tmp;
1078dbcf02cSchristos 	TCHAR name[10];
1088dbcf02cSchristos 	DWORD val, i;
1098dbcf02cSchristos 
1108dbcf02cSchristos 	ret = RegOpenKeyEx(WPA_KEY_ROOT, WPA_KEY_PREFIX TEXT("\\interfaces"),
1118dbcf02cSchristos 			   0, KEY_ENUMERATE_SUB_KEYS | KEY_CREATE_SUB_KEY,
1128dbcf02cSchristos 			   &hk);
1138dbcf02cSchristos 	if (ret != ERROR_SUCCESS)
1148dbcf02cSchristos 		return false;
1158dbcf02cSchristos 
1168dbcf02cSchristos 	id = -1;
1178dbcf02cSchristos 
1188dbcf02cSchristos 	for (i = 0; ; i++) {
1198dbcf02cSchristos 		TCHAR name[255];
1208dbcf02cSchristos 		DWORD namelen;
1218dbcf02cSchristos 
1228dbcf02cSchristos 		namelen = 255;
1238dbcf02cSchristos 		ret = RegEnumKeyEx(hk, i, name, &namelen, NULL, NULL, NULL,
1248dbcf02cSchristos 				   NULL);
1258dbcf02cSchristos 
1268dbcf02cSchristos 		if (ret == ERROR_NO_MORE_ITEMS)
1278dbcf02cSchristos 			break;
1288dbcf02cSchristos 
1298dbcf02cSchristos 		if (ret != ERROR_SUCCESS)
1308dbcf02cSchristos 			break;
1318dbcf02cSchristos 
1328dbcf02cSchristos 		if (namelen >= 255)
1338dbcf02cSchristos 			namelen = 255 - 1;
1348dbcf02cSchristos 		name[namelen] = '\0';
1358dbcf02cSchristos 
1368dbcf02cSchristos #ifdef UNICODE
1378dbcf02cSchristos 		QString s((QChar *) name, namelen);
1388dbcf02cSchristos #else /* UNICODE */
1398dbcf02cSchristos 		QString s(name);
1408dbcf02cSchristos #endif /* UNICODE */
1418dbcf02cSchristos 		tmp = s.toInt();
1428dbcf02cSchristos 		if (tmp > id)
1438dbcf02cSchristos 			id = tmp;
1448dbcf02cSchristos 	}
1458dbcf02cSchristos 
1468dbcf02cSchristos 	id += 1;
1478dbcf02cSchristos 
1488dbcf02cSchristos #ifdef UNICODE
1498dbcf02cSchristos 	wsprintf(name, L"%04d", id);
1508dbcf02cSchristos #else /* UNICODE */
1518dbcf02cSchristos 	os_snprintf(name, sizeof(name), "%04d", id);
1528dbcf02cSchristos #endif /* UNICODE */
1538dbcf02cSchristos 	ret = RegCreateKeyEx(hk, name, 0, NULL, 0, KEY_WRITE, NULL, &ihk,
1548dbcf02cSchristos 			     NULL);
1558dbcf02cSchristos 	RegCloseKey(hk);
1568dbcf02cSchristos 	if (ret != ERROR_SUCCESS)
1578dbcf02cSchristos 		return false;
1588dbcf02cSchristos 
1598dbcf02cSchristos #ifdef UNICODE
1608dbcf02cSchristos 	RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ,
1618dbcf02cSchristos 		      (LPBYTE) ifname.unicode(),
1628dbcf02cSchristos 		      (ifname.length() + 1) * sizeof(TCHAR));
1638dbcf02cSchristos 
1648dbcf02cSchristos #else /* UNICODE */
1658dbcf02cSchristos 	RegSetValueEx(ihk, TEXT("adapter"), 0, REG_SZ,
1668dbcf02cSchristos 		      (LPBYTE) ifname.toLocal8Bit(), ifname.length() + 1);
1678dbcf02cSchristos #endif /* UNICODE */
1688dbcf02cSchristos 	RegSetValueEx(ihk, TEXT("config"), 0, REG_SZ,
1698dbcf02cSchristos 		      (LPBYTE) TEXT("default"), 8 * sizeof(TCHAR));
1708dbcf02cSchristos 	RegSetValueEx(ihk, TEXT("ctrl_interface"), 0, REG_SZ,
1718dbcf02cSchristos 		      (LPBYTE) TEXT(""), 1 * sizeof(TCHAR));
1728dbcf02cSchristos 	val = 1;
1738dbcf02cSchristos 	RegSetValueEx(ihk, TEXT("skip_on_error"), 0, REG_DWORD, (LPBYTE) &val,
1748dbcf02cSchristos 		      sizeof(val));
1758dbcf02cSchristos 
1768dbcf02cSchristos 	RegCloseKey(ihk);
1778dbcf02cSchristos 	return true;
1788dbcf02cSchristos }
1798dbcf02cSchristos #endif /* CONFIG_NATIVE_WINDOWS */
1808dbcf02cSchristos 
1818dbcf02cSchristos 
interfaceSelected(QTreeWidgetItem * sel)1828dbcf02cSchristos void AddInterface::interfaceSelected(QTreeWidgetItem *sel)
1838dbcf02cSchristos {
1848dbcf02cSchristos 	if (!sel)
1858dbcf02cSchristos 		return;
1868dbcf02cSchristos 
1878dbcf02cSchristos #ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
1888dbcf02cSchristos 	struct wpa_ctrl *ctrl;
1898dbcf02cSchristos 	int ret;
1908dbcf02cSchristos 	char buf[20], cmd[256];
1918dbcf02cSchristos 	size_t len;
1928dbcf02cSchristos 
1938dbcf02cSchristos 	/*
1948dbcf02cSchristos 	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
1958dbcf02cSchristos 	 * <driver_param>TAB<bridge_name>
1968dbcf02cSchristos 	 */
1978dbcf02cSchristos 	snprintf(cmd, sizeof(cmd),
1988dbcf02cSchristos 		 "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
199*36ebd06eSchristos 		 sel->text(1).toLocal8Bit().constData(),
2008dbcf02cSchristos 		 "default",
201*36ebd06eSchristos 		 sel->text(0).toLocal8Bit().constData(),
2028dbcf02cSchristos 		 "yes", "", "");
2038dbcf02cSchristos 	cmd[sizeof(cmd) - 1] = '\0';
2048dbcf02cSchristos 
2058dbcf02cSchristos 	ctrl = wpa_ctrl_open(NULL);
2068dbcf02cSchristos 	if (ctrl == NULL)
2078dbcf02cSchristos 		return;
2088dbcf02cSchristos 
2098dbcf02cSchristos 	len = sizeof(buf) - 1;
2108dbcf02cSchristos 	ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL);
2118dbcf02cSchristos 	wpa_ctrl_close(ctrl);
2128dbcf02cSchristos 
2138dbcf02cSchristos 	if (ret < 0) {
2148dbcf02cSchristos 		QMessageBox::warning(this, "wpa_gui",
2158dbcf02cSchristos 				     tr("Add interface command could not be "
2168dbcf02cSchristos 					"completed."));
2178dbcf02cSchristos 		return;
2188dbcf02cSchristos 	}
2198dbcf02cSchristos 
2208dbcf02cSchristos 	buf[len] = '\0';
2218dbcf02cSchristos 	if (buf[0] != 'O' || buf[1] != 'K') {
2228dbcf02cSchristos 		QMessageBox::warning(this, "wpa_gui",
2238dbcf02cSchristos 				     tr("Failed to add the interface."));
2248dbcf02cSchristos 		return;
2258dbcf02cSchristos 	}
2268dbcf02cSchristos 
2278dbcf02cSchristos #endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
2288dbcf02cSchristos 
2298dbcf02cSchristos #ifdef CONFIG_NATIVE_WINDOWS
2308dbcf02cSchristos 	if (!addRegistryInterface(sel->text(1))) {
2318dbcf02cSchristos 		QMessageBox::information(this, "wpa_gui",
2328dbcf02cSchristos 					 tr("Failed to add the interface into "
2338dbcf02cSchristos 					    "registry."));
2348dbcf02cSchristos 	}
2358dbcf02cSchristos #endif /* CONFIG_NATIVE_WINDOWS */
2368dbcf02cSchristos 
2378dbcf02cSchristos 	wpagui->selectAdapter(sel->text(1));
2388dbcf02cSchristos 	close();
2398dbcf02cSchristos }
240