From a309912c8b80e89b0968bd7d24f10af8bb0afa20 Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Tue, 16 Feb 2021 12:51:11 -0600 Subject: [PATCH 1/8] RTEMS DHCP: Use safer versions of string functions Use strtok_r rather than strtok Use strlen() rather than harcoded string size. GCC should optimize this to the hardcoded string size, so the result should be the same but maybe prevents future mistakes. replace strncpy() with snprintf() to avoid issues with NULL terminated strings. --- modules/libcom/RTEMS/posix/rtems_init.c | 67 ++++++++++++++++--------- 1 file changed, 44 insertions(+), 23 deletions(-) diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c index 4b082b34d..470905559 100644 --- a/modules/libcom/RTEMS/posix/rtems_init.c +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -707,50 +707,71 @@ dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env) char iName[16]; char *name; char *value; - + char * env_position; + (void)hook; char ifnamebuf[IF_NAMESIZE]; sprintf(ifnamebuf, "%s", getPrimaryNetworkInterface()); while (*env != NULL) { - name = strtok(*env,"="); - value = strtok(NULL,"="); + char const * interface = "interface"; + char const * reason = "reason"; + char const * bound_str = "BOUND"; + + name = strtok_r(*env,"=", &env_position); + value = strtok_r(NULL,"=", &env_position); printf("all out ---> %s = %s\n", name, value); - if (!strncmp(name, "interface", 9) && !strcmp(value, ifnamebuf)) - strncpy(iName, value, 16); - if (!strncmp(name, "reason", 6) && !strncmp(value, "BOUND", 5)){ + + if (!strncmp(name, interface, strlen(interface)) && + !strcmp(value, ifnamebuf)) { + snprintf(iName, sizeof(iName), "%s", value); + } + + if (!strncmp(name, reason, strlen(reason)) && + !strncmp(value, bound_str, strlen(bound_str))) { printf ("Interface %s bounded\n", iName); bound = 1; - } - if (bound) { + } + + if (bound) { // as there is no ntp-support in rtems-libbsd, we call our own client - if(!strncmp(name, "new_ntp_servers", 15)) - strcpy(rtemsInit_NTP_server_ip,value); - if(!strncmp(name, "new_host_name", 13)) + char const * new_ntp_servers = "new_ntp_servers"; + char const * new_host_name = "new_host_name"; + char const * new_tftp_server_name = "new_tftp_server_name"; + + if (!strncmp(name, new_ntp_servers, strlen(new_ntp_servers))) + snprintf(rtemsInit_NTP_server_ip, + sizeof(rtemsInit_NTP_server_ip), + "%s", value); + + if (!strncmp(name, new_host_name, strlen(new_host_name))) sethostname (value, strlen (value)); - if(!strncmp(name, "new_tftp_server_name", 20)){ - //printf(" new_tftp_server_name : %s\n", value); - strncpy(rtems_bsdnet_bootp_server_name,value, sizeof(bootp_server_name_init)); + + if (!strncmp(name, new_tftp_server_name, strlen(new_tftp_server_name))){ + snprintf(rtems_bsdnet_bootp_server_name, + sizeof(bootp_server_name_init), + "%s", value); printf(" rtems_bsdnet_bootp_server_name : %s\n", rtems_bsdnet_bootp_server_name); } if(!strncmp(name, "new_bootfile_name", 20)){ - //printf(" new_bootfile_name : %s\n", value); - strncpy(rtems_bsdnet_bootp_boot_file_name,value, sizeof(bootp_boot_file_name_init)); + snprintf(rtems_bsdnet_bootp_boot_file_name, + sizeof(bootp_boot_file_name_init), + "%s", value); printf(" rtems_bsdnet_bootp_boot_file_name : %s\n", rtems_bsdnet_bootp_boot_file_name); } if(!strncmp(name, "new_rtems_cmdline", 20)){ - //printf(" new_rtems_cmdline : %s\n", value); - strncpy(rtems_bsdnet_bootp_cmdline,value, sizeof(bootp_cmdline_init)); + snprintf(rtems_bsdnet_bootp_cmdline, + sizeof(bootp_cmdline_init), + "%s", value); printf(" rtems_bsdnet_bootp_cmdline : %s\n", rtems_bsdnet_bootp_cmdline); } - // printf("---> %s = %s\n", name, value); - } - ++env; - } + } + ++env; + } if (bound) epicsEventSignal(dhcpDone); - } +} static rtems_dhcpcd_hook dhcpcd_hook = { .name = "ioc boot", From af88e9f6c6e58c88baa23ea810bf4d9b56c8098a Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Tue, 16 Feb 2021 15:12:06 -0600 Subject: [PATCH 2/8] Clean up a couple warnings in RTEMS code --- modules/libcom/RTEMS/posix/rtems_init.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c index 470905559..d192041be 100644 --- a/modules/libcom/RTEMS/posix/rtems_init.c +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -822,7 +822,6 @@ default_network_dhcpcd(void) "option tftp_server_name\n" \ "option bootfile_name\n" \ "define 129 string rtems_cmdline\n"; - "vendopt 129 string rtems_cmdline"; n = write(fd, fhi_cfg, sizeof(fhi_cfg) - 1); assert(n == (ssize_t) sizeof(fhi_cfg) - 1); @@ -991,8 +990,7 @@ POSIX_Init ( void *argument __attribute__((unused))) default_network_set_self_prio(RTEMS_MAXIMUM_PRIORITY - 1U); /* supress all output from bsd network initialization */ - rtems_bsd_vprintf_handler bsd_vprintf_handler_old; - bsd_vprintf_handler_old = rtems_bsd_set_vprintf_handler(rtems_bsd_vprintf_handler_mute); + rtems_bsd_set_vprintf_handler(rtems_bsd_vprintf_handler_mute); sc = rtems_bsd_initialize(); assert(sc == RTEMS_SUCCESSFUL); From 6965f86298dddcdadf124742f0e43756aba1d028 Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Tue, 16 Feb 2021 15:12:28 -0600 Subject: [PATCH 3/8] Change telnetd configuration to use defaults Currently, this configuration doesn't seem to be used yet, but regardless we'll update the settings to use RTEMS defaults. --- modules/libcom/RTEMS/posix/rtems_init.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c index d192041be..141abafea 100644 --- a/modules/libcom/RTEMS/posix/rtems_init.c +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -882,13 +882,14 @@ telnet_pseudoIocsh(char *name, __attribute__((unused))void *arg) /* * Telnet daemon configuration + * 0 or NULL for most fields in thsi struct indicate default values to RTEMS. */ rtems_telnetd_config_table rtems_telnetd_config = { .command = SHELL_ENTRY, .arg = NULL, - .priority = 99, // if RTEMS_NETWORK and .priority == 0 bsd_network_prio should be used ... + .priority = 0, .stack_size = 0, - .client_maximum = 5, // should be 1, on RTEMS and Epics it makes only sense for one connection a time + .client_maximum = 0, .login_check = NULL, .keep_stdio = false }; From a934570cce75fe233dc2cf3c0bdf1a6df50d17f2 Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Mon, 22 Feb 2021 16:08:18 -0600 Subject: [PATCH 4/8] rtems dhcp: remove strncmp on environment vars in favor of strcmp --- modules/libcom/RTEMS/posix/rtems_init.c | 27 +++++++++---------------- 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c index 141abafea..2e3b703b9 100644 --- a/modules/libcom/RTEMS/posix/rtems_init.c +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -715,52 +715,43 @@ dhcpcd_hook_handler(rtems_dhcpcd_hook *hook, char *const *env) sprintf(ifnamebuf, "%s", getPrimaryNetworkInterface()); while (*env != NULL) { - char const * interface = "interface"; - char const * reason = "reason"; - char const * bound_str = "BOUND"; - name = strtok_r(*env,"=", &env_position); value = strtok_r(NULL,"=", &env_position); printf("all out ---> %s = %s\n", name, value); - if (!strncmp(name, interface, strlen(interface)) && + if (!strcmp(name, "interface") && !strcmp(value, ifnamebuf)) { snprintf(iName, sizeof(iName), "%s", value); } - if (!strncmp(name, reason, strlen(reason)) && - !strncmp(value, bound_str, strlen(bound_str))) { - printf ("Interface %s bounded\n", iName); - bound = 1; + if (!strcmp(name, "if_up") && !strcmp(value, "true")) { + printf ("Interface %s is up\n", iName); + bound = true; } if (bound) { // as there is no ntp-support in rtems-libbsd, we call our own client - char const * new_ntp_servers = "new_ntp_servers"; - char const * new_host_name = "new_host_name"; - char const * new_tftp_server_name = "new_tftp_server_name"; - - if (!strncmp(name, new_ntp_servers, strlen(new_ntp_servers))) + if (!strcmp(name, "new_ntp_servers")) snprintf(rtemsInit_NTP_server_ip, sizeof(rtemsInit_NTP_server_ip), "%s", value); - if (!strncmp(name, new_host_name, strlen(new_host_name))) + if (!strcmp(name, "new_host_name")) sethostname (value, strlen (value)); - if (!strncmp(name, new_tftp_server_name, strlen(new_tftp_server_name))){ + if (!strcmp(name, "new_tftp_server_name")) { snprintf(rtems_bsdnet_bootp_server_name, sizeof(bootp_server_name_init), "%s", value); printf(" rtems_bsdnet_bootp_server_name : %s\n", rtems_bsdnet_bootp_server_name); } - if(!strncmp(name, "new_bootfile_name", 20)){ + if(!strcmp(name, "new_bootfile_name")){ snprintf(rtems_bsdnet_bootp_boot_file_name, sizeof(bootp_boot_file_name_init), "%s", value); printf(" rtems_bsdnet_bootp_boot_file_name : %s\n", rtems_bsdnet_bootp_boot_file_name); } - if(!strncmp(name, "new_rtems_cmdline", 20)){ + if(!strcmp(name, "new_rtems_cmdline")){ snprintf(rtems_bsdnet_bootp_cmdline, sizeof(bootp_cmdline_init), "%s", value); From 3bdfb9ec456c671ccf1af9ec65ca2219eb38acc1 Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Mon, 22 Feb 2021 16:11:50 -0600 Subject: [PATCH 5/8] Increase DHCP timeouts RTEMS dhcp will wait indefinitely for a response. rtems_init.c will wait on DHCP for 10 minutes, before timing out and starting main(). Note that rtems should still be waiting in the background and a dhcp connection could still come up after this timeout. --- modules/libcom/RTEMS/posix/rtems_init.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c index 2e3b703b9..bc286e113 100644 --- a/modules/libcom/RTEMS/posix/rtems_init.c +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -806,13 +806,14 @@ default_network_dhcpcd(void) assert(n == (ssize_t) sizeof(default_cfg) - 1); static const char fhi_cfg[] = - "nodhcp6\n" \ - "ipv4only\n" \ - "option ntp_servers\n" \ - "option rtems_cmdline\n" \ - "option tftp_server_name\n" \ - "option bootfile_name\n" \ - "define 129 string rtems_cmdline\n"; + "nodhcp6\n" + "ipv4only\n" + "option ntp_servers\n" + "option rtems_cmdline\n" + "option tftp_server_name\n" + "option bootfile_name\n" + "define 129 string rtems_cmdline\n" + "timeout 0"; n = write(fd, fhi_cfg, sizeof(fhi_cfg) - 1); assert(n == (ssize_t) sizeof(fhi_cfg) - 1); @@ -1009,13 +1010,12 @@ POSIX_Init ( void *argument __attribute__((unused))) // wait for dhcp done ... should be if SYNCDHCP is used epicsEventWaitStatus stat; - int counter = 2; - do { - printf("\n ---- Wait for DHCP done ...\n"); - stat = epicsEventWaitWithTimeout(dhcpDone, 5.0); - } while ((stat == epicsEventWaitTimeout) && (--counter > 0)); + printf("\n ---- Waiting for DHCP ...\n"); + stat = epicsEventWaitWithTimeout(dhcpDone, 600); if (stat == epicsEventOK) epicsEventDestroy(dhcpDone); + else if (stat == epicsEventWaitTimeout) + printf("\n ---- DHCP timed out!\n"); else printf("\n ---- dhcpDone Event Unknown state %d\n", stat); From 74fa27d316d81fc590299107e4680c600540832b Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Mon, 22 Feb 2021 16:18:00 -0600 Subject: [PATCH 6/8] Add commented code that starts an RTEMS shell, useful for debugging In the future, it would be nice to add an ioc shell command to launch into an RTEMS shell, but for now, it can be helpful when debugging to enable this section for poking around in an RTEMS shell check network configuration and stuff like that. --- modules/libcom/RTEMS/posix/rtems_init.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/modules/libcom/RTEMS/posix/rtems_init.c b/modules/libcom/RTEMS/posix/rtems_init.c index bc286e113..10795a66e 100644 --- a/modules/libcom/RTEMS/posix/rtems_init.c +++ b/modules/libcom/RTEMS/posix/rtems_init.c @@ -1115,10 +1115,20 @@ POSIX_Init ( void *argument __attribute__((unused))) atexit(exitHandler); errlogFlush(); printf ("***** Starting EPICS application *****\n"); + +#if 0 +// Start an rtems shell before main, for debugging RTEMS system issues + rtems_shell_init("SHLL", RTEMS_MINIMUM_STACK_SIZE * 4, + 100, "/dev/console", + false, true, + NULL); +#endif + result = main ((sizeof argv / sizeof argv[0]) - 1, argv); printf ("***** IOC application terminating *****\n"); epicsThreadSleep(1.0); epicsExit(result); + #if defined(__rtems__) delayedPanic("will reset rtems ... end of POSIX_Init"); #endif From dc1bf9106e305395ba059bcd4f85c76ff549596f Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Mon, 22 Feb 2021 16:20:01 -0600 Subject: [PATCH 7/8] osiSockTest: Give a clearer error message if sendto() fails --- modules/libcom/test/osiSockTest.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/libcom/test/osiSockTest.c b/modules/libcom/test/osiSockTest.c index f2adb41cd..84ae84458 100644 --- a/modules/libcom/test/osiSockTest.c +++ b/modules/libcom/test/osiSockTest.c @@ -325,7 +325,9 @@ void udpSockFanoutTestIface(const osiSockAddr* addr) /* test to see if send is possible (not EPERM) */ ret = sendto(sender, buf.bytes, sizeof(buf.bytes), 0, &addr->sa, sizeof(*addr)); if(ret!=(int)sizeof(buf.bytes)) { - testDiag("test sendto() error %d (%d)", ret, (int)SOCKERRNO); + char err[256] = {0}; + strerror_r(errno, &err, sizeof(err)); + testDiag("test sendto() error %d (%d): %s", ret, (int)SOCKERRNO, err); goto cleanup; } From a1d073955f0059bdcde8e833fea8208e1e396f35 Mon Sep 17 00:00:00 2001 From: Brendan Chandler Date: Mon, 22 Feb 2021 16:21:07 -0600 Subject: [PATCH 8/8] makeTestfile: revert to e1000 rt18139 was not working with DHCP when running osiSockTest. e1000 exhibits the annoying ~60s delay when rtems initializes, but at least the tests get a network connection for now. --- src/tools/makeTestfile.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/makeTestfile.pl b/src/tools/makeTestfile.pl index 686e3c1a3..ecf3ea47a 100644 --- a/src/tools/makeTestfile.pl +++ b/src/tools/makeTestfile.pl @@ -42,7 +42,7 @@ elsif ($TA =~ /^RTEMS-pc[36]86-qemu$/) { # Run the pc386 and pc686 test harness w/ QEMU $exec = "qemu-system-i386 -m 64 -no-reboot " . "-serial stdio -display none " - . "-net nic,model=rtl8139 -net nic,model=ne2k_pci " + . "-net nic,model=e1000 -net nic,model=ne2k_pci " . "-net user,restrict=yes " . "-append --console=/dev/com1 " . "-kernel $exe";