From 4289d79bbf1f78712682f983dfc3189cb708c0a5 Mon Sep 17 00:00:00 2001 From: Mark Pizzolato Date: Sun, 7 Jun 2020 12:45:41 -0700 Subject: [PATCH] ETHER, SOCK: Update latest from master branch --- sim_ether.c | 52 ++++++++++++++++++++++++++++++---------------------- sim_ether.h | 2 +- sim_sock.c | 31 ++++++++++++++++--------------- sim_sock.h | 8 +++++--- 4 files changed, 52 insertions(+), 41 deletions(-) diff --git a/sim_ether.c b/sim_ether.c index 64182cf5..920714d6 100644 --- a/sim_ether.c +++ b/sim_ether.c @@ -1653,7 +1653,9 @@ static int _eth_get_system_id (char *buf, size_t buf_size) #endif if ((status = RegOpenKeyExA (HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Cryptography", 0, KEY_QUERY_VALUE|KEY_WOW64_64KEY, ®hnd)) != ERROR_SUCCESS) return -1; - reglen = buf_size; + if (buf_size < 37) + return -1; + reglen = buf_size - 1; if ((status = RegQueryValueExA (reghnd, "MachineGuid", NULL, ®type, (LPBYTE)buf, ®len)) != ERROR_SUCCESS) { RegCloseKey (reghnd); return -1; @@ -1672,19 +1674,16 @@ static int _eth_get_system_id (char *buf, size_t buf_size) FILE *f; memset (buf, 0, buf_size); -if ((f = fopen ("/etc/machine-id", "r"))) { - if (fread (buf, 1, buf_size - 1, f)) - fclose (f); - else - fclose (f); - } -else { - if ((f = popen ("hostname", "r"))) { - if (fread (buf, 1, buf_size - 1, f)) - pclose (f); - else - pclose (f); - } +if (buf_size < 37) + return -1; +if ((f = fopen ("/etc/machine-id", "r")) == NULL) + f = popen ("hostname", "r"); +if (f) { + size_t read_size; + + read_size = fread (buf, 1, buf_size - 1, f); + buf[read_size] = '\0'; + fclose (f); } while ((strlen (buf) > 0) && sim_isspace(buf[strlen (buf) - 1])) buf[strlen (buf) - 1] = '\0'; @@ -1959,7 +1958,8 @@ return NULL; t_stat eth_set_async (ETH_DEV *dev, int latency) { #if !defined(USE_READER_THREAD) || !defined(SIM_ASYNCH_IO) -char *msg = "Eth: can't operate asynchronously, must poll\n"; +char *msg = "Eth: Can't operate asynchronously, must poll.\n" + " *** Build with USE_READER_THREAD defined and link with pthreads for asynchronous operation. ***\n"; return sim_messagef (SCPE_NOFNC, "%s", msg); #else int wakeup_needed; @@ -2070,13 +2070,14 @@ if (0 == strncmp("tap:", savname, 4)) { } else { *fd_handle = (SOCKET)tun; - strcpy(savname, devname); + memmove(savname, devname, strlen(devname) + 1); } #if defined (__APPLE__) - if (1) { + if (tun >= 0) { /* Good so far? */ struct ifreq ifr; int s; + /* Now make sure the interface is up */ memset (&ifr, 0, sizeof(ifr)); ifr.ifr_addr.sa_family = AF_INET; strlcpy(ifr.ifr_name, savname, sizeof(ifr.ifr_name)); @@ -2474,13 +2475,20 @@ return SCPE_OK; const char *eth_version (void) { #if defined(HAVE_PCAP_NETWORK) -static char version[256]; +static char version[300]; if (!version[0]) { - if (memcmp(pcap_lib_version(), "Npcap", 5)) - strlcpy(version, pcap_lib_version(), sizeof(version)); - else - snprintf(version, sizeof(version), "Unsupported - %s", pcap_lib_version()); + strlcpy(version, pcap_lib_version(), sizeof(version)); + if (memcmp(pcap_lib_version(), "Npcap", 5) == 0) { + char maj_min[CBUFSIZE]; + char *c = version; + + while (*c && !isdigit (*c)) + ++c; + get_glyph (c, maj_min, ','); + if (strcmp ("0.9990", maj_min) < 0) + snprintf(version, sizeof(version), "Unsupported - %s", pcap_lib_version()); + } } return version; #else diff --git a/sim_ether.h b/sim_ether.h index 598f8b89..f3edab8d 100644 --- a/sim_ether.h +++ b/sim_ether.h @@ -381,7 +381,7 @@ t_stat ethq_destroy(ETH_QUE* que); /* release FIFO queue */ const char *eth_capabilities(void); t_stat sim_ether_test (DEVICE *dptr); /* unit test routine */ -#if !defined(SIM_TEST_INIT) /* Need stubs for test APIs */ +#if !defined(SIM_TEST_INIT) /* Need stubs for test APIs */ #define SIM_TEST_INIT #define SIM_TEST(xxx) #endif diff --git a/sim_sock.c b/sim_sock.c index a1388183..6f357cc3 100644 --- a/sim_sock.c +++ b/sim_sock.c @@ -1,6 +1,6 @@ /* sim_sock.c: OS-dependent socket routines - Copyright (c) 2001-2019, Robert M Supnik + Copyright (c) 2001-2010, Robert M Supnik Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), @@ -23,7 +23,6 @@ used in advertising or otherwise to promote the sale, use or other dealings in this Software without prior written authorization from Robert M Supnik. - 22-Nov-19 MP Latest 4.X changes 15-Oct-12 MP Added definitions needed to detect possible tcp connect failures 25-Sep-12 MP Reworked for RFC3493 interfaces supporting IPv6 and IPv4 @@ -263,6 +262,7 @@ if (service) { char *c; port = strtoul(service, &c, 10); + port = htons((unsigned short)port); if ((port == 0) || (*c != '\0')) { switch (hints->ai_socktype) { @@ -432,6 +432,10 @@ return 0; #if !defined(IPV6_V6ONLY) /* Older XP environments may not define IPV6_V6ONLY */ #define IPV6_V6ONLY 27 /* Treat wildcard bind as AF_INET6-only. */ #endif +#if defined(TEST_INFO_STUBS) +#undef IPV6_V6ONLY +#undef AF_INET6 +#endif /* Dynamic DLL load variables */ #ifdef _WIN32 static HINSTANCE hLib = 0; /* handle to DLL */ @@ -684,7 +688,7 @@ return 0; port = pointer to buffer for IP port (may be NULL), 0 = none localport = pointer to buffer for local IP port (may be NULL), 0 = none - result = status (SCPE_OK on complete success or SCPE_ARG if + result = status (0 on complete success or -1 if parsing can't happen due to bad syntax, a value is out of range, a result can't fit into a result buffer, a service name doesn't exist, or a validation name @@ -739,6 +743,12 @@ load_ws2 (); #if defined (SIGPIPE) signal (SIGPIPE, SIG_IGN); /* no pipe signals */ #endif +#if defined(TEST_INFO_STUBS) +/* force use of stubs */ +p_getaddrinfo = (getaddrinfo_func)s_getaddrinfo; +p_getnameinfo = (getnameinfo_func)s_getnameinfo; +p_freeaddrinfo = (freeaddrinfo_func)s_freeaddrinfo; +#endif } void sim_cleanup_sock (void) @@ -918,7 +928,7 @@ if (sta == SOCKET_ERROR) /* bind error? */ if (!(opt_flags & SIM_SOCK_OPT_BLOCKING)) { sta = sim_setnonblock (newsock); /* set nonblocking */ if (sta == SOCKET_ERROR) /* fcntl error? */ - return sim_err_sock (newsock, "fcntl"); + return sim_err_sock (newsock, "setnonblock"); } sta = listen (newsock, 1); /* listen on socket */ if (sta == SOCKET_ERROR) /* listen error? */ @@ -990,7 +1000,7 @@ if (!(opt_flags & SIM_SOCK_OPT_BLOCKING)) { sta = sim_setnonblock (newsock); /* set nonblocking */ if (sta == SOCKET_ERROR) { /* fcntl error? */ p_freeaddrinfo (result); - return sim_err_sock (newsock, "fcntl"); + return sim_err_sock (newsock, "setnonblock"); } } if ((!(opt_flags & SIM_SOCK_OPT_DATAGRAM)) && (opt_flags & SIM_SOCK_OPT_NODELAY)) { @@ -1064,20 +1074,16 @@ if (newsock == INVALID_SOCKET) { /* error? */ } if (connectaddr != NULL) { *connectaddr = (char *)calloc(1, NI_MAXHOST+1); -#ifdef AF_INET6 p_getnameinfo((struct sockaddr *)&clientname, size, *connectaddr, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); if (0 == memcmp("::ffff:", *connectaddr, 7)) /* is this a IPv4-mapped IPv6 address? */ memmove(*connectaddr, 7+*connectaddr, /* prefer bare IPv4 address */ strlen(*connectaddr) - 7 + 1); /* length to include terminating \0 */ -#else - strcpy(*connectaddr, inet_ntoa(((struct sockaddr_in *)&connectaddr)->s_addr)); -#endif } if (!(opt_flags & SIM_SOCK_OPT_BLOCKING)) { sta = sim_setnonblock (newsock); /* set nonblocking */ if (sta == SOCKET_ERROR) /* fcntl error? */ - return sim_err_sock (newsock, "fcntl"); + return sim_err_sock (newsock, "setnonblock"); } if ((opt_flags & SIM_SOCK_OPT_NODELAY)) { @@ -1152,7 +1158,6 @@ size_t size = addrsize; #endif int ret = 0; -#ifdef AF_INET6 *hostnamebuf = '\0'; *portnamebuf = '\0'; ret = p_getnameinfo(addr, size, hostnamebuf, NI_MAXHOST, NULL, 0, NI_NUMERICHOST); @@ -1161,10 +1166,6 @@ if (0 == memcmp("::ffff:", hostnamebuf, 7)) /* is this a IPv4-mapped IPv6 strlen(hostnamebuf) + 7 - 1); /* length to include terminating \0 */ if (!ret) ret = p_getnameinfo(addr, size, NULL, 0, portnamebuf, NI_MAXSERV, NI_NUMERICSERV); -#else -strcpy(hostnamebuf, inet_ntoa(((struct sockaddr_in *)addr)->s_addr)); -sprintf(portnamebuf, "%d", (int)ntohs(((struct sockaddr_in *)addr)->s_port))); -#endif return ret; } diff --git a/sim_sock.h b/sim_sock.h index 326720c7..f42e8f16 100644 --- a/sim_sock.h +++ b/sim_sock.h @@ -90,8 +90,10 @@ extern "C" { #endif #define WSAEACCES EACCES #define WSAEINTR EINTR -#define INVALID_SOCKET ((SOCKET)-1) -#define SOCKET_ERROR -1 +#define INVALID_SOCKET ((SOCKET)-1) +#if !defined(SOCKET_ERROR) +#define SOCKET_ERROR (-1) +#endif #endif #if defined (VMS) /* VMS unique */ @@ -118,7 +120,7 @@ int sim_parse_addr_ex (const char *cptr, char *host, size_t hostlen, const char SOCKET sim_master_sock_ex (const char *hostport, int *parse_status, int opt_flags); #define sim_master_sock(hostport, parse_status) sim_master_sock_ex(hostport, parse_status, ((sim_switches & SWMASK ('U')) ? SIM_SOCK_OPT_REUSEADDR : 0)) SOCKET sim_connect_sock_ex (const char *sourcehostport, const char *hostport, const char *default_host, const char *default_port, int opt_flags); -#define sim_connect_sock(hostport, default_host, default_port) sim_connect_sock_ex(NULL, hostport, default_host, default_port, 0) +#define sim_connect_sock(hostport, default_host, default_port) sim_connect_sock_ex(NULL, hostport, default_host, default_port, SIM_SOCK_OPT_BLOCKING) SOCKET sim_accept_conn_ex (SOCKET master, char **connectaddr, int opt_flags); #define sim_accept_conn(master, connectaddr) sim_accept_conn_ex(master, connectaddr, 0) int sim_check_conn (SOCKET sock, int rd);