diff -r 00a162d7e6cd src/network-nat.c
--- a/src/network-nat.c Wed May 06 20:17:33 2020 +0100
+++ b/src/network-nat.c Thu May 14 22:15:17 2020 +0100
@@ -146,6 +146,75 @@
network_hwaddr[5] = 0x06;
}
+static void
+network_add_port_forwards(Slirp * restrict slirp, char * restrict portspec, struct in_addr *ros_addr)
+{
+ char *port = portspec;
+
+ rpclog("Networking: Parsing port forward string %s\n", portspec);
+
+#define ERR_POINT(line, pos) do { \
+ char *buf = malloc(pos + 2); \
+ rpclog(" %s\n", line); \
+ if (buf != NULL) { \
+ memset(buf, ' ', pos); \
+ buf[pos] = '^'; \
+ buf[pos + 1] = '\0'; \
+ rpclog(" %s\n", buf); \
+ free(buf); \
+ } \
+} while (0)
+
+ while (port && *port != '\0') {
+ int is_udp = 0;
+ int host_port = 0;
+ int ros_port = 0;
+ int rv = 0;
+ struct in_addr bind;
+
+ bind.s_addr = 0;
+
+ if (strncmp(port, "udp:", 4) == 0) {
+ is_udp = 1;
+ } else if (strncmp(port, "tcp:", 4) != 0) {
+ rpclog("Networking: bailing parsing port forwards, unknown protocol:\n");
+ ERR_POINT(portspec, port - portspec);
+ return;
+ }
+
+ port += 4;
+
+ host_port = strtol(port, &port, 0);
+ if (host_port == 0) {
+ rpclog("Networking: bailing parsing port forwards, invalid host port:\n");
+ ERR_POINT(portspec, port - portspec);
+ return;
+ }
+
+ /* skip colon */
+ port++;
+ ros_port = strtol(port, &port, 0);
+ if (ros_port == 0) {
+ rpclog("Networking: bailing parsing port forwards, invalid RISC OS port:\n");
+ ERR_POINT(portspec, port - portspec);
+ return;
+ }
+
+ while (*port != '\0' && *port == ' ') {
+ port++;
+ }
+
+ rpclog("Networking: forwarding host %s port %d to RISC OS port %d\n",
+ is_udp ? "UDP" : "TCP", host_port, ros_port);
+
+ rv = slirp_add_hostfwd(slirp, is_udp, bind, host_port, *ros_addr, ros_port);
+ if (rv != 0) {
+ rpclog("Networking: unable to forward: %d\n", rv);
+ }
+ }
+#undef ERR_POINT
+}
+
/**
*/
static void
@@ -172,7 +241,8 @@
net_addr, mask, host, vhostname, "", bootfile, dhcp, dns, NULL);
// TODO log NAT details
- }
+ network_add_port_forwards(nat.slirp, config.network_port_forwards, &dhcp);
+ };
}
int
@@ -195,6 +265,8 @@
}
}
+
+
return 1;
}
diff -r 00a162d7e6cd src/network.c
--- a/src/network.c Wed May 06 20:17:33 2020 +0100
+++ b/src/network.c Thu May 14 22:15:17 2020 +0100
@@ -207,11 +207,12 @@
* @param networktype New network type value
* @param bridgename String of new bridgename value (zero terminated), caller owns (copy taken)
* @param ipaddress String of new ipaddress value (zero terminated), caller owns (copy taken)
+ * @param forwards String of new forwards value (zero terminated), caller owns (copy taken)
* @return Non-zero if these config changes require an emulator restart
*/
int
network_config_changed(NetworkType network_type, const char *bridgename,
- const char *ipaddress)
+ const char *ipaddress, const char *forwards)
{
int restart_required = 0;
@@ -272,6 +273,32 @@
}
}
+ if (forwards == NULL && config.network_port_forwards != NULL) {
+ /* Forwarding is being turned off */
+ free(config.network_port_forwards);
+ config.network_port_forwards = NULL;
+ if (config.network_type == NetworkType_NAT) {
+ restart_required = 1;
+ }
+ } else if (forwards != NULL && config.network_port_forwards == NULL) {
+ /* Forwarding is being turned on */
+ config.network_port_forwards = strdup(forwards);
+ if (config.network_type == NetworkType_NAT) {
+ restart_required = 1;
+ }
+ } else {
+ if (forwards != NULL && config.network_port_forwards != NULL &&
+ strcmp(forwards, config.network_port_forwards) != 0)
+ {
+ /* Forwarding changed */
+ free(config.network_port_forwards);
+ config.network_port_forwards = strdup(forwards);
+ if (config.network_type == NetworkType_NAT) {
+ restart_required = 1;
+ }
+ }
+ }
+
// Save the settings to the rpc.cfg file
config_save(&config);
diff -r 00a162d7e6cd src/network.h
--- a/src/network.h Wed May 06 20:17:33 2020 +0100
+++ b/src/network.h Thu May 14 22:15:17 2020 +0100
@@ -46,7 +46,7 @@
void strcpyfromhost(uint32_t dest, const char *source);
int network_config_changed(NetworkType networktype, const char *bridgename,
- const char *ipaddress);
+ const char *ipaddress, const char *forwards);
int network_macaddress_parse(const char *macaddress, uint8_t hwaddr[6]);
/* Functions provided by each host platform's network code */
diff -r 00a162d7e6cd src/qt5/network_dialog.cpp
--- a/src/qt5/network_dialog.cpp Wed May 06 20:17:33 2020 +0100
+++ b/src/qt5/network_dialog.cpp Thu May 14 22:15:17 2020 +0100
@@ -57,6 +57,14 @@
tunnelling_hbox->addWidget(tunnelling_label);
tunnelling_hbox->addWidget(tunnelling_name);
+ forwards_label = new QLabel("Port forwards");
+ forwards_name = new QLineEdit(QString("tcp:8080:80"));
+ forwards_name->setMinimumWidth(192);
+ forwards_hbox = new QHBoxLayout();
+ forwards_hbox->insertSpacing(0, 48);
+ forwards_hbox->addWidget(forwards_label);
+ forwards_hbox->addWidget(forwards_name);
+
// Create Buttons
buttons_box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
@@ -65,6 +73,7 @@
vbox = new QVBoxLayout(this);
vbox->addWidget(net_off);
vbox->addWidget(net_nat);
+ vbox->addLayout(forwards_hbox);
vbox->addWidget(net_bridging);
vbox->addLayout(bridge_hbox);
@@ -117,6 +126,14 @@
tunnelling_label->setEnabled(false);
tunnelling_name->setEnabled(false);
}
+
+ if (net_nat->isChecked()) {
+ forwards_label->setEnabled(true);
+ forwards_name->setEnabled(true);
+ } else {
+ forwards_label->setEnabled(false);
+ forwards_name->setEnabled(false);
+ }
}
/**
@@ -125,8 +142,8 @@
void
NetworkDialog::dialog_accepted()
{
- QByteArray ba_bridgename, ba_ipaddress;
- char *bridgename, *ipaddress;
+ QByteArray ba_bridgename, ba_ipaddress, ba_forwards;
+ char *bridgename, *ipaddress, *forwards;
NetworkType network_type = NetworkType_Off;
// Take a copy of the existing config
@@ -161,7 +178,7 @@
// Update network config in emulator thread
emit this->emulator.network_config_updated_signal(network_type,
- bridge_name->text(), tunnelling_name->text());
+ bridge_name->text(), tunnelling_name->text(), forwards_name->text());
ba_bridgename = bridge_name->text().toUtf8();
bridgename = ba_bridgename.data();
@@ -169,6 +186,9 @@
ba_ipaddress = tunnelling_name->text().toUtf8();
ipaddress = ba_ipaddress.data();
+ ba_forwards = forwards_name->text().toUtf8();
+ forwards = ba_forwards.data();
+
// Apply configuration settings from Dialog to config_copy
config_copy->network_type = network_type;
if (config_copy->bridgename == NULL) {
@@ -183,6 +203,12 @@
free(config_copy->ipaddress);
config_copy->ipaddress = strdup(ipaddress);
}
+ if (config_copy->network_port_forwards == NULL) {
+ config_copy->network_port_forwards = strdup(forwards);
+ } else if (strcmp(config_copy->network_port_forwards, forwards) != 0) {
+ free(config_copy->network_port_forwards);
+ config_copy->network_port_forwards = strdup(forwards);
+ }
}
/**
@@ -235,4 +261,9 @@
if(config_copy->ipaddress && config_copy->ipaddress[0] != '\0') {
tunnelling_name->setText(config_copy->ipaddress);
}
+
+ if(config_copy->network_port_forwards && config_copy->network_port_forwards[0] != '\0') {
+ forwards_name->setText(config_copy->network_port_forwards);
+ }
+
}
diff -r 00a162d7e6cd src/qt5/network_dialog.h
--- a/src/qt5/network_dialog.h Wed May 06 20:17:33 2020 +0100
+++ b/src/qt5/network_dialog.h Thu May 14 22:15:17 2020 +0100
@@ -59,6 +59,10 @@
QLineEdit *tunnelling_name;
QHBoxLayout *tunnelling_hbox;
+ QLabel *forwards_label;
+ QLineEdit *forwards_name;
+ QHBoxLayout *forwards_hbox;
+
QDialogButtonBox *buttons_box;
QVBoxLayout *vbox;
diff -r 00a162d7e6cd src/qt5/rpc-qt5.cpp
--- a/src/qt5/rpc-qt5.cpp Wed May 06 20:17:33 2020 +0100
+++ b/src/qt5/rpc-qt5.cpp Thu May 14 22:15:17 2020 +0100
@@ -916,7 +916,7 @@
* @param ipaddress
*/
void
-Emulator::network_config_updated(NetworkType network_type, QString bridgename, QString ipaddress)
+Emulator::network_config_updated(NetworkType network_type, QString bridgename, QString ipaddress, QString forwards)
{
QByteArray ba_bridgename = bridgename.toUtf8();
const char *bridge_name = ba_bridgename.constData();
@@ -924,7 +924,10 @@
QByteArray ba_ipaddress = ipaddress.toUtf8();
const char *ip_address = ba_ipaddress.constData();
- if (network_config_changed(network_type, bridge_name, ip_address)) {
+ QByteArray ba_forwards = forwards.toUtf8();
+ const char *port_forwards = ba_forwards.constData();
+
+ if (network_config_changed(network_type, bridge_name, ip_address, port_forwards)) {
this->reset();
}
}
diff -r 00a162d7e6cd src/qt5/rpc-qt5.h
--- a/src/qt5/rpc-qt5.h Wed May 06 20:17:33 2020 +0100
+++ b/src/qt5/rpc-qt5.h Thu May 14 22:15:17 2020 +0100
@@ -69,7 +69,7 @@
void mouse_hack_signal();
void mouse_twobutton_signal();
void config_updated_signal(Config *new_config, Model new_model);
- void network_config_updated_signal(NetworkType network_type, QString bridgename, QString ipaddress);
+ void network_config_updated_signal(NetworkType network_type, QString bridgename, QString ipaddress, QString forwards);
void show_fullscreen_message_off_signal();
public slots:
@@ -102,7 +102,7 @@
void mouse_hack();
void mouse_twobutton();
void config_updated(Config *new_config, Model new_model);
- void network_config_updated(NetworkType network_type, QString bridgename, QString ipaddress);
+ void network_config_updated(NetworkType network_type, QString bridgename, QString ipaddress, QString forwards);
void show_fullscreen_message_off();
private:
diff -r 00a162d7e6cd src/qt5/rpcemu.pro
--- a/src/qt5/rpcemu.pro Wed May 06 20:17:33 2020 +0100
+++ b/src/qt5/rpcemu.pro Thu May 14 22:15:17 2020 +0100
@@ -1,6 +1,6 @@
# http://doc.qt.io/qt-5/qmake-tutorial.html
-CONFIG += debug_and_release
+CONFIG += debug_and_release dynarec
QT += core widgets gui multimedia
diff -r 00a162d7e6cd src/qt5/settings.cpp
--- a/src/qt5/settings.cpp Wed May 06 20:17:33 2020 +0100
+++ b/src/qt5/settings.cpp Thu May 14 22:15:17 2020 +0100
@@ -182,6 +182,8 @@
} else {
config->network_capture = NULL;
}
+
+ config->network_port_forwards = strdup(settings.value("forward_ports", "").toString().toUtf8().data());
}
@@ -259,4 +261,9 @@
if (config->network_capture) {
settings.setValue("network_capture", config->network_capture);
}
+
+ if (config->network_port_forwards) {
+ settings.setValue("forward_ports", config->network_port_forwards);
+ }
+
}
diff -r 00a162d7e6cd src/rpcemu.c
--- a/src/rpcemu.c Wed May 06 20:17:33 2020 +0100
+++ b/src/rpcemu.c Thu May 14 22:15:17 2020 +0100
@@ -91,6 +91,7 @@
0, /* cpu_idle */
1, /* show_fullscreen_message */
NULL, /* network_capture */
+ NULL, /* port fowards */
};
/* Performance measuring variables */
diff -r 00a162d7e6cd src/rpcemu.h
--- a/src/rpcemu.h Wed May 06 20:17:33 2020 +0100
+++ b/src/rpcemu.h Thu May 14 22:15:17 2020 +0100
@@ -138,6 +138,7 @@
int cpu_idle; /**< Attempt to reduce CPU usage */
int show_fullscreen_message; /**< Show explanation of how to leave fullscreen, on entering fullscreen */
char *network_capture; ///< Path to capture network traffic file, or NULL to disable
+ char *network_port_forwards; ///< Space-separated port forwards in the form: <tcp|udp>:hostport:roport
} Config;
extern Config config;
Attached in a small patch that lets you forward ports from your host
machine through to your RISC OS guest when using NAT networking mode.
I have added a new config option in rpc.cfg, called forward_ports with
the following syntax:
<tcp|udp>:host_port:riscos_port[ ...]
So, say you are running a web server listening on HTTP (port 80) and
HTTPS (port 8443), you might say:
forward_ports=tcp:8080:80 tcp:8443:443
This will mean anything connecting to port 8080 on your host machine
will be proxied through to port 80 inside RISC OS. and the same for
8443 to 80. Note that under most UNIX systems you will need extra
permissions (ie, root) to forward host ports <= 1024.
The parser will log with user-friendly messages if you get the syntax
wrong (unknown protocol, unparsable number, etc) and point a little
arrow at where the problem is.
I have added a suitable but primitive text entry box to the Networking
Configuration dialogue. I did not enjoy this bit: GUI programming and
configuration dialogue state machines are terrible things.
B.
No comments:
Post a Comment