1 //==========================================================================
5 // Stand-alone network logical I/O support for RedBoot
7 //==========================================================================
8 //####ECOSGPLCOPYRIGHTBEGIN####
9 // -------------------------------------------
10 // This file is part of eCos, the Embedded Configurable Operating System.
11 // Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
12 // Copyright (C) 2002, 2003, 2004 Gary Thomas
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //==========================================================================
42 //#####DESCRIPTIONBEGIN####
45 // Contributors: gthomas
50 // This code is part of RedBoot (tm).
52 //####DESCRIPTIONEND####
54 //==========================================================================
58 #include <cyg/hal/hal_misc.h> // Helper functions
59 #include <cyg/hal/hal_if.h> // HAL I/O interfaces
60 #include <cyg/hal/drv_api.h>
61 #include <cyg/hal/hal_intr.h>
62 #include <cyg/infra/cyg_ass.h> // assertion macros
64 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
65 #include <flash_config.h>
67 RedBoot_config_option("GDB connection port",
71 CYGNUM_REDBOOT_NETWORKING_TCP_PORT
73 RedBoot_config_option("Network debug at boot time",
79 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
80 RedBoot_config_option("Default network device",
84 CYGDAT_REDBOOT_DEFAULT_NETWORK_DEVICE
87 // Note: the following options are related. If 'bootp' is false, then
88 // the other values are used in the configuration. Because of the way
89 // that configuration tables are generated, they should have names which
90 // are related. The configuration options will show up lexicographically
91 // ordered, thus the peculiar naming. In this case, the 'use' option is
92 // negated (if false, the others apply) which makes the names even more
95 #ifndef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
96 #define CYGSEM_REDBOOT_DEFAULT_NO_BOOTP 0
98 RedBoot_config_option("Use BOOTP for network configuration",
100 ALWAYS_ENABLED, true,
102 !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
104 RedBoot_config_option("Local IP address",
110 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
111 RedBoot_config_option("Local IP address mask",
117 RedBoot_config_option("Gateway IP address",
124 RedBoot_config_option("Default server IP address",
126 ALWAYS_ENABLED, true,
131 // Note: the following options are related too.
132 RedBoot_config_option("Force console for special debug messages",
134 ALWAYS_ENABLED, true,
138 RedBoot_config_option("Console number for special debug messages",
140 "info_console_force", true,
146 #define TCP_CHANNEL CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
152 static tcp_socket_t tcp_sock;
154 static int _timeout = 500;
155 static int orig_console, orig_debug;
157 static int in_buflen = 0;
158 static unsigned char in_buf[64];
159 static unsigned char *in_bufp;
160 static int out_buflen = 0;
161 static unsigned char out_buf[1024];
162 static unsigned char *out_bufp;
163 static bool flush_output_lines = false;
165 // Functions in this module
166 static void net_io_flush(void);
167 static void net_io_revert_console(void);
168 static void net_io_putc(void*, cyg_uint8);
170 // Special characters used by Telnet - must be interpretted here
171 #define TELNET_IAC 0xFF // Interpret as command (escape)
172 #define TELNET_IP 0xF4 // Interrupt process
173 #define TELNET_WONT 0xFC // I Won't do it
174 #define TELNET_DO 0xFD // Will you XXX
175 #define TELNET_TM 0x06 // Time marker (special DO/WONT after IP)
178 _net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
180 if (in_buflen == 0) {
182 if (tcp_sock.state == _CLOSE_WAIT) {
183 // This connection is breaking
184 if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) {
185 __tcp_close(&tcp_sock);
189 if (tcp_sock.state == _CLOSED) {
190 // The connection is gone
191 net_io_revert_console();
195 in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf));
198 if (show_tcp && (in_buflen > 0)) {
200 old_console = start_console();
201 diag_printf("%s:%d\n", __FUNCTION__, __LINE__);
202 diag_dump_buf(in_buf, in_buflen);
203 end_console(old_console);
217 net_io_getc_nonblock(void* __ch_data, cyg_uint8* ch)
221 if (!_net_io_getc_nonblock(__ch_data, ch))
224 if (gdb_active || *ch != TELNET_IAC)
227 // Telnet escape - need to read/handle more
228 while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
232 // The other special case - escaped escape
235 // Special case for ^C == Interrupt Process
237 // Just in case the other end needs synchronizing
238 net_io_putc(__ch_data, TELNET_IAC);
239 net_io_putc(__ch_data, TELNET_WONT);
240 net_io_putc(__ch_data, TELNET_TM);
245 while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
246 // Respond with WONT option
247 net_io_putc(__ch_data, TELNET_IAC);
248 net_io_putc(__ch_data, TELNET_WONT);
249 net_io_putc(__ch_data, esc);
250 return false; // Ignore this whole thing!
257 net_io_getc(void* __ch_data)
260 int idle_timeout = 10; // 10ms
262 CYGARC_HAL_SAVE_GP();
264 if (net_io_getc_nonblock(__ch_data, &ch)) break;
265 if (--idle_timeout == 0) {
270 CYGARC_HAL_RESTORE_GP();
283 old_console = start_console();
284 diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
285 diag_dump_buf(out_buf, out_buflen);
286 end_console(old_console);
289 n = __tcp_write_block(&tcp_sock, bp, out_buflen);
291 // The connection is gone!
292 net_io_revert_console();
297 out_bufp = out_buf; out_buflen = 0;
298 // Check interrupt flag
299 if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {
300 CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
301 cyg_hal_user_break(0);
306 net_io_putc(void* __ch_data, cyg_uint8 c)
308 static bool have_dollar, have_hash;
309 static int hash_count;
311 CYGARC_HAL_SAVE_GP();
313 if (c == '$') have_dollar = true;
314 if (have_dollar && (c == '#')) {
318 if ((++out_buflen == sizeof(out_buf)) ||
319 (flush_output_lines && c == '\n') ||
320 (have_hash && (++hash_count == 3))) {
324 CYGARC_HAL_RESTORE_GP();
328 net_io_write(void* __ch_data, const cyg_uint8* __buf, cyg_uint32 __len)
332 old_console = start_console();
333 diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
334 end_console(old_console);
336 CYGARC_HAL_SAVE_GP();
339 net_io_putc(__ch_data, *__buf++);
341 CYGARC_HAL_RESTORE_GP();
346 net_io_read(void* __ch_data, cyg_uint8* __buf, cyg_uint32 __len)
350 old_console = start_console();
351 diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
352 end_console(old_console);
354 CYGARC_HAL_SAVE_GP();
357 *__buf++ = net_io_getc(__ch_data);
359 CYGARC_HAL_RESTORE_GP();
364 net_io_getc_timeout(void* __ch_data, cyg_uint8* ch)
369 CYGARC_HAL_SAVE_GP();
370 net_io_flush(); // Make sure any output has been sent
371 delay_count = _timeout;
374 res = net_io_getc_nonblock(__ch_data, ch);
375 if (res || 0 == delay_count--)
379 CYGARC_HAL_RESTORE_GP();
385 net_io_control(void *__ch_data, __comm_control_cmd_t __func, ...)
387 static int vector = 0;
389 static int irq_state = 0;
391 CYGARC_HAL_SAVE_GP();
394 case __COMMCTL_IRQ_ENABLE:
397 vector = eth_drv_int_vector();
399 HAL_INTERRUPT_UNMASK(vector);
401 case __COMMCTL_IRQ_DISABLE:
405 vector = eth_drv_int_vector();
407 HAL_INTERRUPT_MASK(vector);
409 case __COMMCTL_DBG_ISR_VECTOR:
412 case __COMMCTL_SET_TIMEOUT:
416 va_start(ap, __func);
419 _timeout = va_arg(ap, cyg_uint32);
424 case __COMMCTL_FLUSH_OUTPUT:
427 case __COMMCTL_ENABLE_LINE_FLUSH:
428 flush_output_lines = true;
430 case __COMMCTL_DISABLE_LINE_FLUSH:
431 flush_output_lines = false;
436 CYGARC_HAL_RESTORE_GP();
441 net_io_isr(void *__ch_data, int* __ctrlc,
442 CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
446 CYGARC_HAL_SAVE_GP();
448 if (net_io_getc_nonblock(__ch_data, &ch)) {
453 CYGARC_HAL_RESTORE_GP();
454 return CYG_ISR_HANDLED;
463 CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
465 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
467 if ( flash_get_config( "info_console_force", &i, CONFIG_BOOL) )
469 if ( ! flash_get_config( "info_console_number", &i, CONFIG_INT) )
470 i = 0; // the default, if that call failed.
472 CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
475 CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
481 end_console(int old_console)
483 // Restore original console
484 CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
489 net_io_revert_console(void)
491 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
492 console_selected = false;
494 CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console);
495 CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug);
500 net_io_assume_console(void)
502 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
503 console_selected = true;
505 console_echo = false;
506 orig_console = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
507 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
508 orig_debug = CYGACC_CALL_IF_SET_DEBUG_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
509 CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL);
517 hal_virtual_comm_table_t* comm;
518 int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
520 // Setup procs in the vector table
521 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
522 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
523 //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
524 CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write);
525 CYGACC_COMM_IF_READ_SET(*comm, net_io_read);
526 CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc);
527 CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc);
528 CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control);
529 CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr);
530 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout);
532 // Disable interrupts via this interface to set static
533 // state into correct state.
534 net_io_control( comm, __COMMCTL_IRQ_DISABLE );
536 // Restore original console
537 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
542 __tcp_listen(&tcp_sock, gdb_port);
543 state = tcp_sock.state;
545 diag_printf("show tcp = %p\n", (void *)&show_tcp);
549 // Check for incoming TCP debug connection
551 net_io_test(bool is_idle)
553 if (!is_idle) return; // Only care about idle case
554 if (!have_net) return;
556 if (state != tcp_sock.state) {
557 // Something has changed
558 if (tcp_sock.state == _ESTABLISHED) {
559 // A new connection has arrived
560 net_io_assume_console();
561 in_bufp = in_buf; in_buflen = 1; *in_bufp = '\r';
562 out_bufp = out_buf; out_buflen = 0;
564 if (tcp_sock.state == _CLOSED) {
565 net_io_init(); // Get ready for another connection
568 state = tcp_sock.state;
571 // This schedules the 'net_io_test()' function to be run by RedBoot's
572 // main command loop when idle (i.e. when no input arrives after some
574 RedBoot_idle(net_io_test, RedBoot_IDLE_NETIO);
577 // Network initialization
579 #include <cyg/io/eth/eth_drv.h>
580 #include <cyg/io/eth/netdev.h>
581 #include <cyg/hal/hal_tables.h>
583 // Define table boundaries
584 CYG_HAL_TABLE_BEGIN( __NETDEVTAB__, netdev );
585 CYG_HAL_TABLE_END( __NETDEVTAB_END__, netdev );
587 RedBoot_init(net_init, RedBoot_INIT_LAST);
592 diag_printf("IP: %s", inet_ntoa((in_addr_t *)&__local_ip_addr));
593 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
594 diag_printf("/%s", inet_ntoa((in_addr_t *)&__local_ip_mask));
595 diag_printf(", Gateway: %s\n", inet_ntoa((in_addr_t *)&__local_ip_gate));
599 diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr));
600 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
606 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
608 flash_get_IP(char *id, ip_addr_t *val)
613 if (flash_get_config(id, &my_ip, CONFIG_IP)) {
614 if (my_ip[0] != 0 || my_ip[1] != 0 ||
615 my_ip[2] != 0 || my_ip[3] != 0) {
616 // 'id' is set to something so let it override any static IP
618 (*val)[i] = my_ip[i];
624 static cyg_netdevtab_entry_t *
625 net_devtab_entry(unsigned index)
627 cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index];
629 if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__)
636 net_devname(unsigned index)
638 cyg_netdevtab_entry_t *t = net_devtab_entry(index);
645 net_devindex(char *name)
650 for (index = 0; (devname = net_devname(index)) != NULL; index++)
651 if (!strcmp(name, devname))
659 diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
660 __local_enet_sc->dev_name,
661 __local_enet_addr[0],
662 __local_enet_addr[1],
663 __local_enet_addr[2],
664 __local_enet_addr[3],
665 __local_enet_addr[4],
666 __local_enet_addr[5]);
672 cyg_netdevtab_entry_t *t;
674 struct eth_drv_sc *primary_net = (struct eth_drv_sc *)0;
675 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
676 char *default_devname;
679 #ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR
683 // Set defaults as appropriate
684 #ifdef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
689 #ifdef CYGDBG_REDBOOT_NET_DEBUG
694 gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT;
695 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
696 // Fetch values from saved config data, if available
697 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
698 flash_get_config("net_device", &default_devname, CONFIG_NETPORT);
700 flash_get_config("net_debug", &net_debug, CONFIG_BOOL);
701 flash_get_config("gdb_port", &gdb_port, CONFIG_INT);
702 flash_get_config("bootp", &use_bootp, CONFIG_BOOL);
704 flash_get_IP("bootp_my_ip", &__local_ip_addr);
705 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
706 flash_get_IP("bootp_my_ip_mask", &__local_ip_mask);
707 flash_get_IP("bootp_my_gateway_ip", &__local_ip_gate);
711 # ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
712 // Don't override if the user has deliberately set something more
714 if (0 == cyg_io_eth_net_debug)
715 cyg_io_eth_net_debug = net_debug;
718 // Make sure the recv buffers are set up
719 eth_drv_buffers_init();
722 // Initialize network device(s).
723 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
724 default_index = net_devindex(default_devname);
725 if (default_index < 0)
727 #ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
728 if ((t = net_devtab_entry(default_index)) != NULL && t->init(t)) {
729 t->status = CYG_NETDEVTAB_STATUS_AVAIL;
730 primary_net = __local_enet_sc;
734 for (index = 0; (t = net_devtab_entry(index)) != NULL; index++) {
735 #ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
736 if (index == default_index)
740 t->status = CYG_NETDEVTAB_STATUS_AVAIL;
741 if (primary_net == (struct eth_drv_sc *)0) {
742 primary_net = __local_enet_sc;
744 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
745 if (index == default_index) {
746 primary_net = __local_enet_sc;
751 __local_enet_sc = primary_net;
753 if (!__local_enet_sc) {
754 diag_printf("No network interfaces found\n");
757 // Initialize the network [if present]
759 if (__bootp_find_local_ip(&my_bootp_info) == 0) {
762 // Is it an unset address, or has it been set to a static addr
763 if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
764 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
766 diag_printf("Can't get BOOTP info for device!\n");
768 diag_printf("Can't get BOOTP info, using default IP address\n");
773 if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
774 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
776 diag_printf("No IP info for device!\n");
778 enet_addr_t enet_addr;
779 have_net = true; // Assume values in FLASH were OK
780 // Tell the world that we are using this fixed IP address
781 if (__arp_request((ip_addr_t *)__local_ip_addr, &enet_addr, 1) >= 0) {
782 diag_printf("Warning: IP address %s in use\n", inet_ntoa((in_addr_t *)&__local_ip_addr));
788 #ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR
789 diag_sprintf(ip_addr, "%d.%d.%d.%d",
790 CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR);
791 inet_aton(ip_addr, &my_bootp_info.bp_siaddr);
793 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
794 flash_get_IP("bootp_server_ip", (ip_addr_t *)&my_bootp_info.bp_siaddr);
796 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
797 redboot_dns_res_init();
804 static char usage[] = "[-b] [-l <local_ip_address>[/<mask_len>]] [-h <server_address>]"
805 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
806 " [-d <dns_server_address]"
810 // Exported CLI function
811 static void do_ip_addr(int argc, char *argv[]);
812 RedBoot_cmd("ip_address",
813 "Set/change IP addresses",
819 do_ip_addr(int argc, char *argv[])
821 struct option_info opts[4];
822 char *ip_addr, *host_addr;
823 bool ip_addr_set, host_addr_set;
824 bool do_bootp = false;
825 struct sockaddr_in host;
826 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
832 init_opts(&opts[0], 'l', true, OPTION_ARG_TYPE_STR,
833 (void *)&ip_addr, (bool *)&ip_addr_set, "local IP address");
834 init_opts(&opts[1], 'h', true, OPTION_ARG_TYPE_STR,
835 (void *)&host_addr, (bool *)&host_addr_set, "default server address");
836 init_opts(&opts[2], 'b', false, OPTION_ARG_TYPE_FLG,
837 &do_bootp, 0, "use BOOTP");
839 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
840 init_opts(&opts[num_opts], 'd', true, OPTION_ARG_TYPE_STR,
841 (void *)&dns_addr, (bool *)&dns_addr_set, "DNS server address");
845 CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
847 if (!scan_opts(argc, argv, 1, opts, num_opts, 0, 0, "")) {
851 if (__bootp_find_local_ip(&my_bootp_info) != 0) {
852 diag_printf("Failed to get BOOTP address\n");
856 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
858 /* see if the (optional) mask length was given */
859 if( (slash_pos = strchr(ip_addr, '/')) ) {
860 unsigned long mask_len;
864 if (!parse_num(slash_pos, &mask_len, 0, 0) ||
865 mask_len <= 0 || mask_len > 32 ) {
866 diag_printf("Invalid mask length: %s\n", slash_pos);
869 mask = htonl((0xffffffff << (32-mask_len))&0xffffffff);
870 memcpy(&__local_ip_mask, &mask, 4);
873 if (!_gethostbyname(ip_addr, (in_addr_t *)&host)) {
874 diag_printf("Invalid local IP address: %s\n", ip_addr);
877 // Of course, each address goes in its own place :-)
878 memcpy(&__local_ip_addr, &host.sin_addr, sizeof(host.sin_addr));
881 if (!_gethostbyname(host_addr, (in_addr_t *)&host)) {
882 diag_printf("Invalid server address: %s\n", host_addr);
885 my_bootp_info.bp_siaddr = host.sin_addr;
887 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS