root/ar5315_microredboot/microredboot/ecos/packages/redboot/current/src/net/net_io.c

Revision 12368, 22.5 kB (checked in by BrainSlayer, 5 months ago)

tftp server added, supports wiligear, ubiquiti and dd-wrt webflash format

Line 
1 //==========================================================================
2 //
3 //      net/net_io.c
4 //
5 //      Stand-alone network logical I/O support for RedBoot
6 //
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
13 //
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.
17 //
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
21 // for more details.
22 //
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.
26 //
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.
33 //
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.
36 //
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####
43 //
44 // Author(s):    gthomas
45 // Contributors: gthomas
46 // Date:         2000-07-14
47 // Purpose:     
48 // Description: 
49 //             
50 // This code is part of RedBoot (tm).
51 //
52 //####DESCRIPTIONEND####
53 //
54 //==========================================================================
55
56 #include <redboot.h>
57 #include <net/net.h>
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
63
64 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
65 #include <flash_config.h>
66
67 RedBoot_config_option("GDB connection port",
68                       gdb_port,
69                       ALWAYS_ENABLED, true,
70                       CONFIG_INT, CYGNUM_REDBOOT_NETWORKING_TCP_PORT);
71 //RedBoot_config_option("Network debug at boot time",
72 //                      net_debug,
73 //                      ALWAYS_ENABLED, true,
74 //                      CONFIG_BOOL,
75 //                      false
76 //    );
77 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
78 RedBoot_config_option("Default network device",
79                       net_device, ALWAYS_ENABLED, true, CONFIG_NETPORT, "");
80 #endif
81 // Note: the following options are related.  If 'bootp' is false, then
82 // the other values are used in the configuration.  Because of the way
83 // that configuration tables are generated, they should have names which
84 // are related.  The configuration options will show up lexicographically
85 // ordered, thus the peculiar naming.  In this case, the 'use' option is
86 // negated (if false, the others apply) which makes the names even more
87 // confusing.
88
89 #ifndef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
90 #define CYGSEM_REDBOOT_DEFAULT_NO_BOOTP 1
91 #endif
92 RedBoot_config_option("Use BOOTP for network configuration",
93                       bootp,
94                       ALWAYS_ENABLED, true,
95                       CONFIG_BOOL, !CYGSEM_REDBOOT_DEFAULT_NO_BOOTP);
96 RedBoot_config_option("Local IP address",
97                       bootp_my_ip, "bootp", false, CONFIG_IP, 0);
98 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
99 RedBoot_config_option("Local IP address mask",
100                       bootp_my_ip_mask, "bootp", false, CONFIG_IP, 0);
101 RedBoot_config_option("Gateway IP address",
102                       bootp_my_gateway_ip, "bootp", false, CONFIG_IP, 0);
103 #endif
104 RedBoot_config_option("Default server IP address",
105                       bootp_server_ip, ALWAYS_ENABLED, true, CONFIG_IP, 0);
106
107 // Note: the following options are related too.
108 RedBoot_config_option("Force console for special debug messages",
109                       info_console_force,
110                       ALWAYS_ENABLED, true, CONFIG_BOOL, false);
111 RedBoot_config_option("Console number for special debug messages",
112                       info_console_number,
113                       "info_console_force", true, CONFIG_INT, 0);
114 #endif
115
116 #define TCP_CHANNEL CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS
117
118 #ifdef DEBUG_TCP
119 int show_tcp = 0;
120 #endif
121
122 static tcp_socket_t tcp_sock;
123 static int state;
124 static int _timeout = 500;
125 static int orig_console, orig_debug;
126
127 static int in_buflen = 0;
128 static unsigned char in_buf[64];
129 static unsigned char *in_bufp;
130 static int out_buflen = 0;
131 static unsigned char out_buf[1024];
132 static unsigned char *out_bufp;
133 static bool flush_output_lines = false;
134
135 // Functions in this module
136 static void net_io_flush(void);
137 static void net_io_revert_console(void);
138 static void net_io_putc(void *, cyg_uint8);
139
140 // Special characters used by Telnet - must be interpretted here
141 #define TELNET_IAC    0xFF      // Interpret as command (escape)
142 #define TELNET_IP     0xF4      // Interrupt process
143 #define TELNET_WONT   0xFC      // I Won't do it
144 #define TELNET_DO     0xFD      // Will you XXX
145 #define TELNET_TM     0x06      // Time marker (special DO/WONT after IP)
146
147 static cyg_bool _net_io_getc_nonblock(void *__ch_data, cyg_uint8 * ch)
148 {
149         if (in_buflen == 0) {
150                 __tcp_poll();
151                 if (tcp_sock.state == _CLOSE_WAIT) {
152                         // This connection is breaking
153                         if (tcp_sock.data_bytes == 0 && tcp_sock.rxcnt == 0) {
154                                 __tcp_close(&tcp_sock);
155                                 return false;
156                         }
157                 }
158                 if (tcp_sock.state == _CLOSED) {
159                         // The connection is gone
160                         net_io_revert_console();
161                         *ch = '\n';
162                         return true;
163                 }
164                 in_buflen = __tcp_read(&tcp_sock, in_buf, sizeof(in_buf));
165                 in_bufp = in_buf;
166 #ifdef DEBUG_TCP
167                 if (show_tcp && (in_buflen > 0)) {
168                         int old_console;
169                         old_console = start_console();
170                         diag_printf("%s:%d\n", __FUNCTION__, __LINE__);
171                         diag_dump_buf(in_buf, in_buflen);
172                         end_console(old_console);
173                 }
174 #endif                          // DEBUG_TCP
175         }
176         if (in_buflen) {
177                 *ch = *in_bufp++;
178                 in_buflen--;
179                 return true;
180         } else {
181                 return false;
182         }
183 }
184
185 static cyg_bool net_io_getc_nonblock(void *__ch_data, cyg_uint8 * ch)
186 {
187         cyg_uint8 esc;
188
189         if (!_net_io_getc_nonblock(__ch_data, ch))
190                 return false;
191
192         if (gdb_active || *ch != TELNET_IAC)
193                 return true;
194
195         // Telnet escape - need to read/handle more
196         while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
197
198         switch (esc) {
199         case TELNET_IAC:
200                 // The other special case - escaped escape
201                 return true;
202         case TELNET_IP:
203                 // Special case for ^C == Interrupt Process
204                 *ch = 0x03;
205                 // Just in case the other end needs synchronizing
206                 net_io_putc(__ch_data, TELNET_IAC);
207                 net_io_putc(__ch_data, TELNET_WONT);
208                 net_io_putc(__ch_data, TELNET_TM);
209                 net_io_flush();
210                 return true;
211         case TELNET_DO:
212                 // Telnet DO option
213                 while (!_net_io_getc_nonblock(__ch_data, &esc)) ;
214                 // Respond with WONT option
215                 net_io_putc(__ch_data, TELNET_IAC);
216                 net_io_putc(__ch_data, TELNET_WONT);
217                 net_io_putc(__ch_data, esc);
218                 return false;   // Ignore this whole thing!
219         default:
220                 return false;
221         }
222 }
223
224 static cyg_uint8 net_io_getc(void *__ch_data)
225 {
226         cyg_uint8 ch;
227         int idle_timeout = 10;  // 10ms
228
229         CYGARC_HAL_SAVE_GP();
230         while (true) {
231                 if (net_io_getc_nonblock(__ch_data, &ch))
232                         break;
233                 if (--idle_timeout == 0) {
234                         net_io_flush();
235                         idle_timeout = 10;
236                 }
237         }
238         CYGARC_HAL_RESTORE_GP();
239         return ch;
240 }
241
242 static void net_io_flush(void)
243 {
244         int n;
245         char *bp = out_buf;
246
247 #ifdef DEBUG_TCP
248         if (show_tcp) {
249                 int old_console;
250                 old_console = start_console();
251                 diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
252                 diag_dump_buf(out_buf, out_buflen);
253                 end_console(old_console);
254         }
255 #endif                          // SHOW_TCP
256         n = __tcp_write_block(&tcp_sock, bp, out_buflen);
257         if (n < 0) {
258                 // The connection is gone!
259                 net_io_revert_console();
260         } else {
261                 out_buflen -= n;
262                 bp += n;
263         }
264         out_bufp = out_buf;
265         out_buflen = 0;
266         // Check interrupt flag
267         if (CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG()) {
268                 CYGACC_CALL_IF_CONSOLE_INTERRUPT_FLAG_SET(0);
269                 cyg_hal_user_break(0);
270         }
271 }
272
273 static void net_io_putc(void *__ch_data, cyg_uint8 c)
274 {
275         static bool have_dollar, have_hash;
276         static int hash_count;
277
278         CYGARC_HAL_SAVE_GP();
279         *out_bufp++ = c;
280         if (c == '$')
281                 have_dollar = true;
282         if (have_dollar && (c == '#')) {
283                 have_hash = true;
284                 hash_count = 0;
285         }
286         if ((++out_buflen == sizeof(out_buf)) ||
287             (flush_output_lines && c == '\n') ||
288             (have_hash && (++hash_count == 3))) {
289                 net_io_flush();
290                 have_dollar = false;
291         }
292         CYGARC_HAL_RESTORE_GP();
293 }
294
295 static void
296 net_io_write(void *__ch_data, const cyg_uint8 * __buf, cyg_uint32 __len)
297 {
298         int old_console;
299
300         old_console = start_console();
301         diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
302         end_console(old_console);
303 #if 0
304         CYGARC_HAL_SAVE_GP();
305
306         while (__len-- > 0)
307                 net_io_putc(__ch_data, *__buf++);
308
309         CYGARC_HAL_RESTORE_GP();
310 #endif
311 }
312
313 static void net_io_read(void *__ch_data, cyg_uint8 * __buf, cyg_uint32 __len)
314 {
315         int old_console;
316
317         old_console = start_console();
318         diag_printf("%s.%d\n", __FUNCTION__, __LINE__);
319         end_console(old_console);
320 #if 0
321         CYGARC_HAL_SAVE_GP();
322
323         while (__len-- > 0)
324                 *__buf++ = net_io_getc(__ch_data);
325
326         CYGARC_HAL_RESTORE_GP();
327 #endif
328 }
329
330 static cyg_bool net_io_getc_timeout(void *__ch_data, cyg_uint8 * ch)
331 {
332         int delay_count;
333         cyg_bool res;
334
335         CYGARC_HAL_SAVE_GP();
336         net_io_flush();         // Make sure any output has been sent
337         delay_count = _timeout;
338
339         for (;;) {
340                 res = net_io_getc_nonblock(__ch_data, ch);
341                 if (res || 0 == delay_count--)
342                         break;
343         }
344
345         CYGARC_HAL_RESTORE_GP();
346
347         return res;
348 }
349
350 static int net_io_control(void *__ch_data, __comm_control_cmd_t __func, ...)
351 {
352         static int vector = 0;
353         int ret = 0;
354         static int irq_state = 0;
355
356         CYGARC_HAL_SAVE_GP();
357
358         switch (__func) {
359         case __COMMCTL_IRQ_ENABLE:
360                 irq_state = 1;
361                 if (vector == 0) {
362                         vector = eth_drv_int_vector();
363                 }
364                 HAL_INTERRUPT_UNMASK(vector);
365                 break;
366         case __COMMCTL_IRQ_DISABLE:
367                 ret = irq_state;
368                 irq_state = 0;
369                 if (vector == 0) {
370                         vector = eth_drv_int_vector();
371                 }
372                 HAL_INTERRUPT_MASK(vector);
373                 break;
374         case __COMMCTL_DBG_ISR_VECTOR:
375                 ret = vector;
376                 break;
377         case __COMMCTL_SET_TIMEOUT:
378                 {
379                         va_list ap;
380
381                         va_start(ap, __func);
382
383                         ret = _timeout;
384                         _timeout = va_arg(ap, cyg_uint32);
385
386                         va_end(ap);
387                         break;
388                 }
389         case __COMMCTL_FLUSH_OUTPUT:
390                 net_io_flush();
391                 break;
392         case __COMMCTL_ENABLE_LINE_FLUSH:
393                 flush_output_lines = true;
394                 break;
395         case __COMMCTL_DISABLE_LINE_FLUSH:
396                 flush_output_lines = false;
397                 break;
398         default:
399                 break;
400         }
401         CYGARC_HAL_RESTORE_GP();
402         return ret;
403 }
404
405 static int
406 net_io_isr(void *__ch_data, int *__ctrlc,
407            CYG_ADDRWORD __vector, CYG_ADDRWORD __data)
408 {
409         char ch;
410
411         CYGARC_HAL_SAVE_GP();
412         *__ctrlc = 0;
413         if (net_io_getc_nonblock(__ch_data, &ch)) {
414                 if (ch == 0x03) {
415                         *__ctrlc = 1;
416                 }
417         }
418         CYGARC_HAL_RESTORE_GP();
419         return CYG_ISR_HANDLED;
420 }
421
422 // TEMP
423
424 int start_console(void)
425 {
426         int cur_console =
427             CYGACC_CALL_IF_SET_CONSOLE_COMM
428             (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
429
430 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
431         int i = 0;
432         if (flash_get_config("info_console_force", &i, CONFIG_BOOL))
433                 if (i)
434                         if (!flash_get_config
435                             ("info_console_number", &i, CONFIG_INT))
436                                 i = 0;  // the default, if that call failed.
437         if (i)
438                 CYGACC_CALL_IF_SET_CONSOLE_COMM(i);
439         else
440 #endif
441                 CYGACC_CALL_IF_SET_CONSOLE_COMM(0);
442
443         return cur_console;
444 }
445
446 void end_console(int old_console)
447 {
448         // Restore original console
449         CYGACC_CALL_IF_SET_CONSOLE_COMM(old_console);
450 }
451
452 // TEMP
453
454 static void net_io_revert_console(void)
455 {
456 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
457         console_selected = false;
458 #endif
459         CYGACC_CALL_IF_SET_CONSOLE_COMM(orig_console);
460         CYGACC_CALL_IF_SET_DEBUG_COMM(orig_debug);
461         console_echo = true;
462 }
463
464 static void net_io_assume_console(void)
465 {
466 #ifdef CYGPKG_REDBOOT_ANY_CONSOLE
467         console_selected = true;
468 #endif
469         console_echo = false;
470         orig_console =
471             CYGACC_CALL_IF_SET_CONSOLE_COMM
472             (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
473         CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
474         orig_debug =
475             CYGACC_CALL_IF_SET_DEBUG_COMM
476             (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
477         CYGACC_CALL_IF_SET_DEBUG_COMM(TCP_CHANNEL);
478 }
479
480 static void net_io_init(void)
481 {
482         static int init = 0;
483         if (!init) {
484                 hal_virtual_comm_table_t *comm;
485                 int cur =
486                     CYGACC_CALL_IF_SET_CONSOLE_COMM
487                     (CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
488
489                 // Setup procs in the vector table
490                 CYGACC_CALL_IF_SET_CONSOLE_COMM(TCP_CHANNEL);
491                 comm = CYGACC_CALL_IF_CONSOLE_PROCS();
492                 //CYGACC_COMM_IF_CH_DATA_SET(*comm, chan);
493                 CYGACC_COMM_IF_WRITE_SET(*comm, net_io_write);
494                 CYGACC_COMM_IF_READ_SET(*comm, net_io_read);
495                 CYGACC_COMM_IF_PUTC_SET(*comm, net_io_putc);
496                 CYGACC_COMM_IF_GETC_SET(*comm, net_io_getc);
497                 CYGACC_COMM_IF_CONTROL_SET(*comm, net_io_control);
498                 CYGACC_COMM_IF_DBG_ISR_SET(*comm, net_io_isr);
499                 CYGACC_COMM_IF_GETC_TIMEOUT_SET(*comm, net_io_getc_timeout);
500
501                 // Disable interrupts via this interface to set static
502                 // state into correct state.
503                 net_io_control(comm, __COMMCTL_IRQ_DISABLE);
504
505                 // Restore original console
506                 CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
507
508                 init = 1;
509                 gdb_active = false;
510         }
511         __tcp_listen(&tcp_sock, gdb_port);
512         state = tcp_sock.state;
513 #ifdef DEBUG_TCP
514         diag_printf("show tcp = %p\n", (void *)&show_tcp);
515 #endif
516 }
517
518 // Check for incoming TCP debug connection
519 void net_io_test(bool is_idle)
520 {
521         if (!is_idle)
522                 return;         // Only care about idle case
523         if (!have_net)
524                 return;
525         __tcp_poll();
526         if (state != tcp_sock.state) {
527                 // Something has changed
528                 if (tcp_sock.state == _ESTABLISHED) {
529                         // A new connection has arrived
530                         net_io_assume_console();
531                         in_bufp = in_buf;
532                         in_buflen = 1;
533                         *in_bufp = '\r';
534                         out_bufp = out_buf;
535                         out_buflen = 0;
536                 }
537                 if (tcp_sock.state == _CLOSED) {
538                         net_io_init();  // Get ready for another connection
539                 }
540         }
541         state = tcp_sock.state;
542 }
543
544 // This schedules the 'net_io_test()' function to be run by RedBoot's
545 // main command loop when idle (i.e. when no input arrives after some
546 // period of time).
547 RedBoot_idle(net_io_test, RedBoot_IDLE_NETIO);
548
549 //
550 // Network initialization
551 //
552 #include <cyg/io/eth/eth_drv.h>
553 #include <cyg/io/eth/netdev.h>
554 #include <cyg/hal/hal_tables.h>
555
556 // Define table boundaries
557 CYG_HAL_TABLE_BEGIN(__NETDEVTAB__, netdev);
558 CYG_HAL_TABLE_END(__NETDEVTAB_END__, netdev);
559
560 RedBoot_init(net_init, RedBoot_INIT_LAST);
561
562 static void show_addrs(void)
563 {
564         diag_printf("IP: %s", inet_ntoa((in_addr_t *) & __local_ip_addr));
565 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
566         diag_printf("/%s", inet_ntoa((in_addr_t *) & __local_ip_mask));
567         diag_printf(", Gateway: %s\n",
568                     inet_ntoa((in_addr_t *) & __local_ip_gate));
569 #else
570         diag_printf(", ");
571 #endif
572         diag_printf("Default server: %s", inet_ntoa(&my_bootp_info.bp_siaddr));
573 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
574         show_dns();
575 #endif
576         diag_printf("\n");
577 }
578
579 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
580 static void flash_get_IP(char *id, ip_addr_t * val)
581 {
582         ip_addr_t my_ip;
583         int i;
584
585         if (flash_get_config(id, &my_ip, CONFIG_IP)) {
586                 if (my_ip[0] != 0 || my_ip[1] != 0 ||
587                     my_ip[2] != 0 || my_ip[3] != 0) {
588                         // 'id' is set to something so let it override any static IP
589                         for (i = 0; i < 4; i++)
590                                 (*val)[i] = my_ip[i];
591                 }
592         }
593 }
594 #endif
595
596 static cyg_netdevtab_entry_t *net_devtab_entry(unsigned index)
597 {
598         cyg_netdevtab_entry_t *t = &__NETDEVTAB__[index];
599
600         if (t < &__NETDEVTAB__[0] || t >= &__NETDEVTAB_END__)
601                 return NULL;
602
603         return t;
604 }
605
606 const char *net_devname(unsigned index)
607 {
608         cyg_netdevtab_entry_t *t = net_devtab_entry(index);
609         if (t)
610                 return t->name;
611         return NULL;
612 }
613
614 int net_devindex(char *name)
615 {
616         const char *devname;
617         int index;
618
619         for (index = 0; (devname = net_devname(index)) != NULL; index++)
620                 if (!strcmp(name, devname))
621                         return index;
622         return -1;
623 }
624
625 static void show_eth_info(void)
626 {
627         diag_printf("Ethernet %s: MAC address %02x:%02x:%02x:%02x:%02x:%02x\n",
628                     __local_enet_sc->dev_name,
629                     __local_enet_addr[0],
630                     __local_enet_addr[1],
631                     __local_enet_addr[2],
632                     __local_enet_addr[3],
633                     __local_enet_addr[4], __local_enet_addr[5]);
634 }
635
636 void net_init(void)
637 {
638         cyg_netdevtab_entry_t *t;
639         unsigned index;
640         struct eth_drv_sc *primary_net = (struct eth_drv_sc *)0;
641 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
642         char *default_devname;
643         int default_index;
644 #endif
645 #ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR
646         char ip_addr[16];
647 #endif
648
649         // Set defaults as appropriate
650 #ifdef CYGSEM_REDBOOT_DEFAULT_NO_BOOTP
651         use_bootp = false;
652 #else
653         use_bootp = true;
654 #endif
655 #ifdef CYGDBG_REDBOOT_NET_DEBUG
656         net_debug = true;
657 #else
658         net_debug = false;
659 #endif
660         gdb_port = CYGNUM_REDBOOT_NETWORKING_TCP_PORT;
661 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
662         // Fetch values from saved config data, if available
663 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
664         flash_get_config("net_device", &default_devname, CONFIG_NETPORT);
665 #endif
666 //    flash_get_config("net_debug", &net_debug, CONFIG_BOOL);
667         flash_get_config("gdb_port", &gdb_port, CONFIG_INT);
668         flash_get_config("bootp", &use_bootp, CONFIG_BOOL);
669         if (!use_bootp) {
670                 flash_get_IP("bootp_my_ip", &__local_ip_addr);
671 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
672                 flash_get_IP("bootp_my_ip_mask", &__local_ip_mask);
673                 flash_get_IP("bootp_my_gateway_ip", &__local_ip_gate);
674 #endif
675         }
676 #endif
677 # ifdef CYGDBG_IO_ETH_DRIVERS_DEBUG
678         // Don't override if the user has deliberately set something more
679         // verbose.
680         if (0 == cyg_io_eth_net_debug)
681                 cyg_io_eth_net_debug = net_debug;
682 # endif
683         have_net = false;
684         // Make sure the recv buffers are set up
685         eth_drv_buffers_init();
686         __pktbuf_init();
687
688         // Initialize network device(s).
689 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
690         default_index = net_devindex(default_devname);
691         if (default_index < 0)
692                 default_index = 0;
693 #ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
694         if ((t = net_devtab_entry(default_index)) != NULL && t->init(t)) {
695                 t->status = CYG_NETDEVTAB_STATUS_AVAIL;
696                 primary_net = __local_enet_sc;
697         } else
698 #endif
699 #endif
700                 for (index = 0; (t = net_devtab_entry(index)) != NULL; index++) {
701 #ifdef CYGSEM_REDBOOT_NETWORK_INIT_ONE_DEVICE
702                         if (index == default_index)
703                                 continue;
704 #endif
705                         if (t->init(t)) {
706                                 t->status = CYG_NETDEVTAB_STATUS_AVAIL;
707                                 if (primary_net == (struct eth_drv_sc *)0) {
708                                         primary_net = __local_enet_sc;
709                                 }
710 #if defined(CYGHWR_NET_DRIVERS) && (CYGHWR_NET_DRIVERS > 1)
711                                 if (index == default_index) {
712                                         primary_net = __local_enet_sc;
713                                 }
714 #endif
715                         }
716                 }
717         __local_enet_sc = primary_net;
718
719         if (!__local_enet_sc) {
720                 diag_printf("No network interfaces found\n");
721                 return;
722         }
723         // Initialize the network [if present]
724 /*    if (use_bootp) {
725         if (__bootp_find_local_ip(&my_bootp_info) == 0) {
726             have_net = true;
727         } else {
728             // Is it an unset address, or has it been set to a static addr
729             if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
730                 __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
731                 show_eth_info();
732                 diag_printf("Can't get BOOTP info for device!\n");
733             } else {
734                 diag_printf("Can't get BOOTP info, using default IP address\n");
735                 have_net = true;
736             }
737         }
738     } else {
739 */
740         if (__local_ip_addr[0] == 0 && __local_ip_addr[1] == 0 &&
741             __local_ip_addr[2] == 0 && __local_ip_addr[3] == 0) {
742                 __local_ip_addr[0] = 192;
743                 __local_ip_addr[1] = 168;
744                 __local_ip_addr[2] = 1;
745                 __local_ip_addr[3] = 1;
746 //                __local_ip_mask[0]=255;
747 //                __local_ip_mask[1]=255;
748 //                __local_ip_mask[2]=0;
749 //                __local_ip_mask[3]=0;
750         }
751
752         {
753
754                 enet_addr_t enet_addr;
755                 have_net = true;        // Assume values in FLASH were OK
756                 // Tell the world that we are using this fixed IP address
757                 if (__arp_request((ip_addr_t *) __local_ip_addr, &enet_addr, 1)
758                     >= 0) {
759                         diag_printf("Warning: IP address %s in use\n",
760                                     inet_ntoa((in_addr_t *) & __local_ip_addr));
761                 }
762         }
763 //    }
764         if (have_net) {
765                 show_eth_info();
766 #ifdef CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR
767                 diag_sprintf(ip_addr, "%d.%d.%d.%d",
768                              CYGDAT_REDBOOT_DEFAULT_BOOTP_SERVER_IP_ADDR);
769                 inet_aton(ip_addr, &my_bootp_info.bp_siaddr);
770 #endif
771 #ifdef CYGSEM_REDBOOT_FLASH_CONFIG
772                 flash_get_IP("bootp_server_ip",
773                              (ip_addr_t *) & my_bootp_info.bp_siaddr);
774 #endif
775 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
776                 redboot_dns_res_init();
777 #endif
778                 show_addrs();
779                 net_io_init();
780         }
781 }
782
783 static char usage[] =
784     "[-l <local_ip_address>[/<mask_len>]] [-h <server_address>]";
785
786 // Exported CLI function
787 static void do_ip_addr(int argc, char *argv[]);
788 RedBoot_cmd("ip_address", "Set/change IP addresses", usage, do_ip_addr);
789
790 void do_ip_addr(int argc, char *argv[])
791 {
792         struct option_info opts[3];
793         char *ip_addr, *host_addr;
794         bool ip_addr_set, host_addr_set;
795         struct sockaddr_in host;
796 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
797         char *dns_addr;
798         bool dns_addr_set;
799 #endif
800         int num_opts;
801
802         init_opts(&opts[0], 'l', true, OPTION_ARG_TYPE_STR,
803                   (void *)&ip_addr, (bool *) & ip_addr_set, "local IP address");
804         init_opts(&opts[1], 'h', true, OPTION_ARG_TYPE_STR,
805                   (void *)&host_addr, (bool *) & host_addr_set,
806                   "default server address");
807         num_opts = 2;
808 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
809         init_opts(&opts[2], 'd', true, OPTION_ARG_TYPE_STR,
810                   (void *)&dns_addr, (bool *) & dns_addr_set,
811                   "DNS server address");
812         num_opts++;
813 #endif
814
815         CYG_ASSERT(num_opts <= NUM_ELEMS(opts), "Too many options");
816
817         if (!scan_opts(argc, argv, 1, opts, num_opts, 0, 0, "")) {
818                 return;
819         }
820         if (ip_addr_set) {
821 #ifdef CYGSEM_REDBOOT_NETWORKING_USE_GATEWAY
822                 char *slash_pos;
823                 /* see if the (optional) mask length was given */
824                 if ((slash_pos = strchr(ip_addr, '/'))) {
825                         int mask_len;
826                         unsigned long mask;
827                         *slash_pos = '\0';
828                         slash_pos++;
829                         if (!parse_num
830                             (slash_pos, (unsigned long *)&mask_len, 0, 0)
831                             || mask_len <= 0 || mask_len > 32) {
832                                 diag_printf("Invalid mask length: %s\n",
833                                             slash_pos);
834                                 return;
835                         }
836                         mask =
837                             htonl((0xffffffff << (32 - mask_len)) & 0xffffffff);
838                         memcpy(&__local_ip_mask, &mask, 4);
839                 }
840 #endif
841                 if (!_gethostbyname(ip_addr, (in_addr_t *) & host)) {
842                         diag_printf("Invalid local IP address: %s\n", ip_addr);
843                         return;
844                 }
845                 // Of course, each address goes in its own place :-)
846                 memcpy(&__local_ip_addr, &host.sin_addr, sizeof(host.sin_addr));
847         }
848         if (host_addr_set) {
849                 if (!_gethostbyname(host_addr, (in_addr_t *) & host)) {
850                         diag_printf("Invalid server address: %s\n", host_addr);
851                         return;
852                 }
853                 my_bootp_info.bp_siaddr = host.sin_addr;
854         }
855 #ifdef CYGPKG_REDBOOT_NETWORKING_DNS
856         if (dns_addr_set) {
857                 set_dns(dns_addr);
858         }
859 #endif
860         show_addrs();
861         if (!have_net) {
862                 have_net = true;
863                 net_io_init();
864         }
865 }
866
867 // EOF net_io.c
Note: See TracBrowser for help on using the browser.