diff --git a/src/syncterm/Manual.txt b/src/syncterm/Manual.txt
index 88f980aede217fe580c0ac651101fc434fadb7e2..da912fe6db884473b9ace07bdaa7d48123ff70a1 100644
--- a/src/syncterm/Manual.txt
+++ b/src/syncterm/Manual.txt
@@ -15,19 +15,19 @@ If you need help with SyncTERM, the best places are:
    Connect to irc.synchro.net and find Deuce in #Synchronet.  Ask your
    question, then idle.  I can take hours to respond.  Do not give up,
    this is the quickest way to get a response.
-2) E-Mail:
+2) SourceForge:
+   The official SyncTERM project page at
+   http://www.sf.net/projects/syncterm has a bug tracker and other
+   features that will email me and provide tracking for issues that
+   are filed.
+3) E-Mail:
    I am usually fairly responsive to emails sent to me at
    shurd@sasktel.net.  Please describe your issue as clearly as possible.
-3) Dove-Net:
+4) Dove-Net:
    I usually read Dove-Net regularly, and many other users can often
    help with support issues.  Ask questions in the Hardware/Software Help
    sub.  If your local BBS does not carry Dove-Net, you can telnet to
    vert.synchro.net and leave messages there.
-4) SourceForge:
-   The official SyncTERM project page at
-   http://www.sf.net/projects/syncterm has a bug tracker and other
-   features that will email me and provide tracking for issues that
-   are filed.
 
 Throughout this document, I will mention things which are not supported.
 These are things which I don't normally test, and are unlikely to work
@@ -69,7 +69,7 @@ build system is used.  There are a number of optional dependencies, and
 a large number of supported compile flags (many of which are shared with
 Synchronet).
 
-The biggest optional dependency is SDL 1.2 (from http://libsdl.org).
+The biggest optional dependency is SDL 2 (from http://libsdl.org).
 SyncTERM can use SDL for both graphics and sound.  X11 can also be used
 for graphics, and OSS, ALSA, or Portaudio can also provide sound.  These
 use run-time linking, so at compile time, only the headers are needed.
diff --git a/src/syncterm/bbslist.c b/src/syncterm/bbslist.c
index 39e67b357d6f54d4ac8e37aa2a8186efe8e2e227..cc1995c71c65bb47795f3be9bef9fe635704eb04 100644
--- a/src/syncterm/bbslist.c
+++ b/src/syncterm/bbslist.c
@@ -2,6 +2,7 @@
 
 #include <dirwrap.h>
 #include <ini_file.h>
+#include <netwrap.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -2956,16 +2957,9 @@ show_bbslist(char *current, int connected)
 							    &(list[listcount - 1]->conn_type), NULL, "Connection Type",
 							    &(conn_types[1])) >= 0) {
 								list[listcount - 1]->conn_type++;
-								if ((list[listcount - 1]->conn_type != CONN_TYPE_MODEM)
-								    && (list[listcount - 1]->conn_type
-								    != CONN_TYPE_SERIAL)
-								    && (list[listcount - 1]->conn_type
-								    != CONN_TYPE_SERIAL_NORTS)
-								    && (list[listcount - 1]->conn_type
-								    != CONN_TYPE_SHELL)) {
+								if (IS_NETWORK_CONN(list[listcount - 1]->conn_type)) {
 									/* Default address to name, if appears to be address */
-									if (strchr(list[listcount - 1]->name, ' ') == NULL
-										&& strchr(list[listcount - 1]->name, '.') != NULL)
+									if (isResolvableHostname(list[listcount - 1]->name))
 										SAFECOPY(list[listcount - 1]->addr, list[listcount - 1]->name);
                                                                         /* Set the port too */
 									j = conn_ports[list[listcount - 1]->conn_type];
diff --git a/src/syncterm/conn.h b/src/syncterm/conn.h
index 82cb1d9e4e6cdad685e438c5ea017ff69d44aa81..ff39ccd7a4b047a914b8919964a5d9381d007895 100644
--- a/src/syncterm/conn.h
+++ b/src/syncterm/conn.h
@@ -45,6 +45,16 @@ enum {
 	CONN_TYPE_TERMINATOR
 };
 
+#define IS_NETWORK_CONN(x) (                \
+	((x) == CONN_TYPE_RLOGIN) ||         \
+	((x) == CONN_TYPE_RLOGIN_REVERSED) || \
+	((x) == CONN_TYPE_TELNET) ||           \
+	((x) == CONN_TYPE_RAW) ||               \
+	((x) == CONN_TYPE_SSH) ||                \
+	((x) == CONN_TYPE_SSHNA) ||               \
+	((x) == CONN_TYPE_MBBS_GHOST) ||           \
+	((x) == CONN_TYPE_TELNETS))
+
 struct conn_api {
 	int               (*connect)(struct bbslist *bbs);
 	int               (*close)(void);
diff --git a/src/xpdev/netwrap.c b/src/xpdev/netwrap.c
index 40c807ed1878035483f46821dffd025f247897da..3abd399f73c3a3d00596500e070922d386f426da 100644
--- a/src/xpdev/netwrap.c
+++ b/src/xpdev/netwrap.c
@@ -172,6 +172,125 @@ const char* IPv4AddressToStr(uint32_t addr, char* dest, size_t size)
 #endif
 }
 
+/*
+ * While RFC-952 limits a name to 24 characters, this is never enforced.
+ * RFC-952 also doesn't allow beginning or ending with a hyphen.
+ * RFC-952 also bans starting with a digit.
+ * RFC-1123 explicitly overrode the restriction against starting with a digit.
+ * RFC-1123 implicitly overrode the length restriction.
+ *
+ * The limit of 63 characters for a name comes from DNS, as does the 253
+ * (254 with trailing dot) overall limit.  If DNS isn't used, it's chaos.
+ */
+static bool
+isValidHostnameString(const char *str)
+{
+	size_t pos;
+	size_t seglen = 0;
+	size_t totallen = 0;
+	size_t segcount = 0;
+	bool last_was_hyphen = false;
+
+	while (*str) {
+		if ((*str >= 'a' && *str <= 'z')
+		    || (*str >= 'A' && *str <= 'Z')
+		    || (*str >= '0' && *str <= '9')
+		    || (*str == '-')
+		    || (*str == '.')) {
+			if (*str == '.') {
+				if (last_was_hyphen) {
+					return false;
+				}
+				if (seglen == 0) {
+					return false;
+				}
+				seglen = 0;
+			}
+			else {
+				if (seglen == 0) {
+					if (*str == '-') {
+						return false;
+					}
+					segcount++;
+				}
+				seglen++;
+				if (seglen > 63) {
+					return false;
+				}
+			}
+			totallen++;
+			if (totallen > 253) {
+				// Allow a trailing dot
+				if (totallen != 254 || *str != '.') {
+					return false;
+				}
+			}
+			last_was_hyphen = (*str == '-');
+		}
+		else {
+			return false;
+		}
+		str++;
+	}
+
+	return true;
+}
+
+bool
+isValidAddressString(const char *str)
+{
+	struct sockaddr_in in;
+	struct sockaddr_in6 in6;
+
+	/*
+	 * Per RFC-1123, we need to check for valid IP address first
+	 */
+	if (xp_inet_pton(AF_INET, str, &in) != -1)
+		return true;
+	if (xp_inet_pton(AF_INET6, str, &in6) != -1)
+		return true;
+
+	return false;
+}
+
+bool
+isValidHostname(const char *str)
+{
+	/*
+	 * Per RFC-1123, we need to check for valid IP address first
+	 */
+	if (isValidAddressString(str))
+		return true;
+
+	return isValidHostnameString(str);
+}
+
+bool
+isResolvableHostname(const char *str)
+{
+	if (!isValidHostname(str)) {
+		return false;
+	}
+
+	struct addrinfo hints = {0};
+	struct addrinfo *res = NULL;
+	const char portnum[2] = "1";
+
+	hints.ai_flags = PF_UNSPEC;
+	hints.ai_family = PF_UNSPEC;
+	hints.ai_socktype = SOCK_STREAM;
+	hints.ai_protocol = IPPROTO_TCP;
+	hints.ai_flags = AI_NUMERICSERV;
+#ifdef AI_ADDRCONFIG
+	hints.ai_flags |= AI_ADDRCONFIG;
+#endif
+	if (getaddrinfo(str, portnum, &hints, &res) != 0) {
+		return false;
+	}
+	freeaddrinfo(res);
+	return true;
+}
+
 #if NETWRAP_TEST
 int main(int argc, char** argv)
 {
diff --git a/src/xpdev/netwrap.h b/src/xpdev/netwrap.h
index c1dffd8f206222cfce41120bdfb5da75a7af0a5a..2863fe140977b20a375bfbfc2c12fa5c9fe9afad 100644
--- a/src/xpdev/netwrap.h
+++ b/src/xpdev/netwrap.h
@@ -45,6 +45,9 @@ DLLEXPORT void			freeNameServerList(str_list_t);
 DLLEXPORT const char*	IPv4AddressToStr(uint32_t, char* dest, size_t size);
 DLLEXPORT uint32_t		parseIPv4Address(const char*);
 DLLEXPORT struct in6_addr parseIPv6Address(const char*);
+DLLEXPORT bool isValidHostname(const char *str);
+DLLEXPORT bool isValidAddressString(const char *str);
+DLLEXPORT bool isResolvableHostname(const char *str);
 
 #if defined(__cplusplus)
 }