]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/httpd/v2_0/src/monitor.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / httpd / v2_0 / src / monitor.c
1 /* =================================================================
2  *
3  *      monitor.c
4  *
5  *      An HTTP system monitor 
6  *
7  * ================================================================= 
8  * ####ECOSGPLCOPYRIGHTBEGIN####
9  * -------------------------------------------
10  * This file is part of eCos, the Embedded Configurable Operating
11  * System.
12  * Copyright (C) 2002 Nick Garnett.
13  * Copyright (C) 2003 Andrew Lunn
14  * 
15  * eCos is free software; you can redistribute it and/or modify it
16  * under the terms of the GNU General Public License as published by
17  * the Free Software Foundation; either version 2 or (at your option)
18  * any later version.
19  * 
20  * eCos is distributed in the hope that it will be useful, but
21  * WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23  * General Public License for more details.
24  * 
25  * You should have received a copy of the GNU General Public License
26  * along with eCos; if not, write to the Free Software Foundation,
27  * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
28  * 
29  * As a special exception, if other files instantiate templates or
30  * use macros or inline functions from this file, or you compile this
31  * file and link it with other works to produce a work based on this
32  * file, this file does not by itself cause the resulting work to be
33  * covered by the GNU General Public License. However the source code
34  * for this file must still be made available in accordance with
35  * section (3) of the GNU General Public License.
36  * 
37  * This exception does not invalidate any other reasons why a work
38  * based on this file might be covered by the GNU General Public
39  * License.
40  *
41  * -------------------------------------------
42  * ####ECOSGPLCOPYRIGHTEND####
43  * =================================================================
44  * #####DESCRIPTIONBEGIN####
45  * 
46  *  Author(s):    nickg@calivar.com
47  *  Contributors: nickg@calivar.com, andrew.lunn@ascom.ch
48  *  Date:         2002-10-14
49  *  Purpose:      
50  *  Description:  
51  *               
52  * ####DESCRIPTIONEND####
53  * 
54  * =================================================================
55  */
56
57 #include <pkgconf/system.h>
58 #include <pkgconf/isoinfra.h>
59 #include <pkgconf/net.h>
60 #include <pkgconf/httpd.h>
61 #include <pkgconf/kernel.h>
62
63 #include <cyg/infra/cyg_trac.h>        /* tracing macros */
64 #include <cyg/infra/cyg_ass.h>         /* assertion macros */
65
66 #include <cyg/httpd/httpd.h>
67
68 #include <cyg/kernel/kapi.h>
69 #ifdef CYGPKG_KERNEL_INSTRUMENT
70 #include <cyg/kernel/instrmnt.h>
71 #include <cyg/kernel/instrument_desc.h>
72 #endif
73
74 #include <unistd.h>
75 #include <ctype.h>
76
77 /* ================================================================= */
78 /* Include all the necessary network headers by hand. We need to do
79  * this so that _KERNEL is correctly defined, or not, for specific
80  * headers so we can use both the external API and get at internal
81  * kernel structures.
82  */
83
84 #define _KERNEL
85 #include <sys/param.h>
86 #undef _KERNEL
87 #include <sys/socket.h>
88 #include <sys/ioctl.h>
89 #include <sys/errno.h>
90 #include <sys/time.h>
91 #include <netdb.h>
92 #define _KERNEL
93
94 #include <sys/sysctl.h>
95 #include <net/if.h>
96 #include <ifaddrs.h>
97 #include <netinet/in.h>
98 #include <netinet/ip.h>
99 #include <netinet/ip_icmp.h>
100 #include <net/route.h>
101 #include <net/if_dl.h>
102
103 #include <sys/protosw.h>
104 #include <netinet/in_pcb.h>
105 #include <netinet/udp.h>
106 #include <netinet/tcp.h>
107 #include <netinet/tcp_timer.h>
108 #include <netinet/ip_var.h>
109 #include <netinet/icmp_var.h>
110 #include <netinet/udp_var.h>
111 #include <netinet/tcp_var.h>
112 #ifdef CYGPKG_NET_INET6
113 #include <netinet/ip6.h>
114 #include <net/if_var.h>
115 #include <netinet6/ip6_var.h>
116 #include <netinet6/in6_var.h>
117 #include <netinet/icmp6.h>
118 #endif
119
120
121 #include <sys/mbuf.h>
122
123 #include <cyg/io/eth/eth_drv_stats.h>
124
125 /* ================================================================= */
126 /* Use this when a thread appears to have no name.
127  */
128
129 #define NULL_THREAD_NAME "----------"
130
131 /* ================================================================= */
132 /* Draw navigation bar
133  *
134  * This draws a simple table containing links to the various monitor
135  * pages at the current position in the HTML stream.
136  */
137
138 static void draw_navbar( FILE *client )
139 {
140     html_para_begin( client, "" );
141     
142     html_table_begin( client, "border cellpadding=\"4\"" );
143     {
144         html_table_row_begin(client, "" );
145         {
146             html_table_data_begin( client, "" );
147             html_image( client, "/monitor/ecos.gif", "eCos logo", "" );
148             html_table_data_begin( client, "" );
149             html_url( client, "Threads", "/monitor/threads.html");
150             html_table_data_begin( client, "" );
151             html_url( client, "Interrupts", "/monitor/interrupts.html");
152             html_table_data_begin( client, "" );
153             html_url( client, "Memory", "/monitor/memory.html");
154             html_table_data_begin( client, "" );
155             html_url( client, "Network", "/monitor/network.html");
156 #ifdef CYGPKG_KERNEL_INSTRUMENT
157             html_table_data_begin( client, "" );
158             html_url( client, "Instrumentation", "/monitor/instrument.html");
159 #endif
160         }
161         html_table_row_end( client );
162     }
163     html_table_end( client );
164 }
165
166 /* ================================================================= */
167 /* Index page
168  *
169  * A simple introductory page matching "/monitor" and
170  * "/monitor/index.html".
171  */
172
173 static char monitor_index_blurb[] =
174 "<p>This is the eCos System Monitor. It presents a simple web monitor "
175 "and control interface for eCos systems.\n"
176 "<p>Use the navigation bar at the bottom of each page to explore."
177 ;
178
179 static cyg_bool cyg_monitor_index( FILE * client, char *filename,
180                                    char *formdata, void *arg )
181 {
182     html_begin(client);
183
184     html_head(client,"eCos System Monitor", "");    
185
186     html_body_begin(client,"");
187     {
188         html_heading(client, 2, "eCos System Monitor" );
189
190         fputs( monitor_index_blurb, client );
191         
192         draw_navbar(client);
193     }
194     html_body_end(client);
195
196     html_end(client);
197     
198     return 1;
199 }
200
201 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_entry,
202                        "/monitor",
203                        cyg_monitor_index,
204                        NULL );
205
206 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_index_entry,
207                        "/monitor/index.html",
208                        cyg_monitor_index,
209                        NULL );
210
211 /* ================================================================= */
212 /* Thread Monitor
213  *
214  * Uses the kapi thread info API to enumerate all the current threads
215  * and generate a table showing their state.
216  */
217
218 static cyg_bool cyg_monitor_threads( FILE * client, char *filename,
219                                      char *formdata, void *arg )
220 {
221     
222     html_begin(client);
223
224 /*    html_head(client,"Thread Monitor", "<meta http-equiv=\"refresh\" content=\"10\">"); */
225     html_head(client,"eCos Thread Monitor", "");    
226
227     html_body_begin(client,"");
228     {
229         html_heading(client, 2, "Thread Monitor" );
230
231         html_table_begin( client, "border" );
232         {
233             cyg_handle_t thread = 0;
234             cyg_uint16 id = 0;
235         
236             html_table_header( client, "Id", "" );
237             html_table_header( client, "State", "" );
238             html_table_header( client, "Set<br>Priority", "" );
239             html_table_header( client, "Current<br>Priority", "" );
240             html_table_header( client, "Name", "" );
241             html_table_header( client, "Stack Base", "" );
242             html_table_header( client, "Stack Size", "" );
243 #ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
244             html_table_header( client, "Stack Used", "" );
245 #endif
246             /* Loop over the threads, and generate a table row for
247              * each.
248              */
249             while( cyg_thread_get_next( &thread, &id ) )
250             {
251                 cyg_thread_info info;
252                 char *state_string;
253
254                 cyg_thread_get_info( thread, id, &info );
255                 
256                 if( info.name == NULL )
257                     info.name = NULL_THREAD_NAME;
258
259                 /* Translate the state into a string.
260                  */
261                 if( info.state == 0 )
262                     state_string = "RUN";
263                 else if( info.state & 0x04 )
264                     state_string = "SUSP";
265                 else switch( info.state & 0x1b )
266                 {
267                 case 0x01: state_string = "SLEEP"; break;
268                 case 0x02: state_string = "CNTSLEEP"; break;
269                 case 0x08: state_string = "CREATE"; break;
270                 case 0x10: state_string = "EXIT"; break;
271                 default: state_string = "????"; break;
272                 }
273
274                 /* Now generate the row.
275                  */
276                 html_table_row_begin(client, "" );
277                 {
278                     html_table_data_begin( client, "" );
279                     fprintf( client, "<a href=\"/monitor/thread-%04x.html\">%04x</a>\n", id,id);
280                     html_table_data_begin( client, "" );
281                     fprintf( client, "%s", state_string);
282                     html_table_data_begin( client, "" );
283                     fprintf( client, "%d", info.set_pri);
284                     html_table_data_begin( client, "" );
285                     fprintf( client, "%d", info.cur_pri);
286                     html_table_data_begin( client, "" );
287                     fputs( info.name, client );
288                     html_table_data_begin( client, "" );
289                     fprintf( client, "%08x", info.stack_base );
290                     html_table_data_begin( client, "" );
291                     fprintf( client, "%d", info.stack_size );
292 #ifdef CYGFUN_KERNEL_THREADS_STACK_MEASUREMENT
293                     html_table_data_begin( client, "" );
294                     fprintf( client, "%d", info.stack_used );
295 #endif
296                 }
297                 html_table_row_end(client);
298                 
299             }
300         }
301         html_table_end( client );
302
303         draw_navbar(client);
304     }
305     html_body_end(client);
306
307     html_end(client);
308     
309     return 1;
310 }
311
312 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_show_threads,
313                        "/monitor/threads.htm*",
314                        cyg_monitor_threads,
315                        NULL );
316
317 /* ================================================================= */
318 /* Thread edit page
319  *
320  * A page on which the thread's state may be edited. This tests forms
321  * handling.
322  */
323
324 static char thread_edit_blurb[] =
325 "<p>This table contains an entry for each property of the thread "
326 "that you can edit. The properties are:\n"
327 "<p><b>State:</b> Change thread's state. The <em>Suspend</em> button "
328 "will suspend the thread. The <em>Run</em> button will undo any previous "
329 "suspends. The <em>Release</em> button will release the thread out of "
330 "any sleep it is currently in.\n"
331 "<p><b>Priority:</b> Change the thread's priority.\n"
332 "<p>Once the new state has been selected, press the <em>Submit</em> "
333 "button to make the change, or <em>Reset</em> to clear it."
334 ;
335
336 static cyg_bool cyg_monitor_thread_edit( FILE * client, char *filename,
337                                          char *formdata, void *arg )
338 {
339     /* If any form data has been supplied, then change the thread's
340      * state accordingly.
341      */
342     if( formdata != NULL )
343     {
344         char *formlist[6];
345         char *state;
346         char *pri_string;
347         char *id_string;
348         cyg_handle_t thread = 0;
349         cyg_uint16 id;
350
351         /* Parse the data */
352         cyg_formdata_parse( formdata, formlist, 6 );
353
354         /* Get the thread id from the hidden control */
355         id_string = cyg_formlist_find( formlist, "thread");
356
357         sscanf( id_string, "%04hx", &id );
358
359         thread = cyg_thread_find( id );
360
361         /* If there is a pri field, change the priority */
362         pri_string = cyg_formlist_find( formlist, "pri");
363
364         if( pri_string != NULL )
365         {
366             cyg_priority_t pri;
367
368             sscanf( pri_string, "%d", &pri );
369
370             cyg_thread_set_priority( thread, pri );
371         }
372
373         /* If there is a state field, change the thread state */
374         state = cyg_formlist_find( formlist, "state");
375
376         if( state != NULL )
377         {
378             if( strcmp( state, "run" ) == 0 )
379                 cyg_thread_resume( thread );
380             if( strcmp( state, "suspend" ) == 0 )
381                 cyg_thread_suspend( thread );
382             if( strcmp( state, "release" ) == 0 )
383                 cyg_thread_release( thread );
384         }
385     }
386
387     /* Now generate a page showing the current thread state, and
388      * including form controls to change it.
389      */
390     
391     html_begin(client);
392
393     html_head(client,"eCos Thread Editor", "");
394
395     html_body_begin(client,"");
396     {
397         cyg_uint16 id;
398         cyg_thread_info info;
399         cyg_handle_t thread = 0;
400         char idbuf[16];
401         
402         sscanf( filename, "/monitor/thread-%04hx.html", &id );
403
404         thread = cyg_thread_find( id );
405         cyg_thread_get_info(thread, id, &info );
406         
407         html_heading(client, 2, "Thread State Editor" );
408
409         html_para_begin( client, "" );
410         
411         fprintf( client, "Editing Thread %04x %s\n",id,
412                  info.name?info.name:NULL_THREAD_NAME);
413
414         fputs( thread_edit_blurb, client );
415         
416         html_form_begin( client, filename, "" );        
417         {
418             html_table_begin( client, "border" );
419             {
420                 html_table_header( client, "Property", "" );
421                 html_table_header( client, "Value", "" );
422
423                 html_table_row_begin(client, "" );
424                 {
425                     html_table_data_begin( client, "" );
426                     fputs( "State", client );
427
428                     html_table_data_begin( client, "" );
429
430                     html_form_input_radio( client, "state", "run", (info.state&0x04)==0 );
431                     fputs( "Run", client );
432                     html_form_input_radio( client, "state", "suspend", (info.state&0x04)!=0 );
433                     fputs( "Suspend", client );
434                     html_form_input_radio( client, "state", "release", 0 );
435                     fputs( "Release", client );
436                 }
437                 html_table_row_end( client );
438
439                 html_table_row_begin(client, "" );
440                 {
441                     html_table_data_begin( client, "" );
442                     fputs( "Priority", client );
443
444                     html_table_data_begin( client, "" );
445                     fprintf(client,"<input type=\"text\" name=\"pri\" size=\"10\" value=\"%d\">\n",
446                             info.set_pri);                    
447                 }
448                 html_table_row_end( client );
449
450             }
451             html_table_end( client );
452
453             /* Add submit and reset buttons */
454             html_form_input(client, "submit", "submit", "Submit", "");                
455             html_form_input(client, "reset", "reset", "Reset", "");
456
457             /* Pass the thread ID through to our next incarnation */
458             sprintf( idbuf, "%04x", id );
459             html_form_input_hidden(client, "thread", idbuf );            
460
461         }
462         html_form_end( client );
463         
464         draw_navbar(client);
465     }
466     html_body_end(client);
467
468     html_end(client);
469     
470     return 1;
471 }
472
473 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_thread_edit_entry,
474                        "/monitor/thread-*",
475                        cyg_monitor_thread_edit,
476                        NULL );
477
478 /* ================================================================= */
479 /* Interrupt monitor
480  *
481  * At present this just generates a table showing which interrupts
482  * have an ISR attached.
483  */
484
485 static cyg_bool cyg_monitor_interrupts( FILE * client, char *filename,
486                                         char *formdata, void *arg )
487 {
488     html_begin(client);
489
490     html_head(client,"eCos Interrupt Monitor", "");
491
492     html_body_begin(client,"");
493     {
494         html_heading(client, 2, "Interrupt Monitor" );
495
496         html_table_begin( client, "border" );
497         {
498             int i;
499             int maxint = CYGNUM_HAL_ISR_MAX;
500
501 #ifdef CYGPKG_HAL_I386
502             maxint = CYGNUM_HAL_ISR_MIN+16;
503 #endif
504             
505             html_table_header( client, "ISR", "" );
506             html_table_header( client, "State", "" );
507             
508             for( i = CYGNUM_HAL_ISR_MIN; i <= maxint ; i++ )
509             {
510                 cyg_bool_t inuse;
511                 HAL_INTERRUPT_IN_USE( i, inuse );
512
513                 html_table_row_begin(client, "" );
514                 {
515                     html_table_data_begin( client, "" );
516                     fprintf( client, "%d", i);
517                     html_table_data_begin( client, "" );
518                     fprintf( client, "%s", inuse?"In Use":"Free");
519                 }
520                 html_table_row_end( client );
521             }
522         }
523         html_table_end( client );
524
525         draw_navbar(client);
526     }
527     html_body_end(client);
528
529     html_end(client);
530     
531     return 1;
532     
533 }
534
535 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_interrupts_entry,
536                        "/monitor/interrupts.htm*",
537                        cyg_monitor_interrupts,
538                        NULL );
539
540 /* ================================================================= */
541 /* Memory monitor
542  *
543  * Generates a table showing a 256 byte page of memory. Form controls
544  * allow changes to the base address and display element size.
545  */
546
547 static cyg_bool cyg_monitor_memory( FILE * client, char *filename,
548                                     char *formdata, void *arg )
549 {
550     char *formlist[10];
551     cyg_uint32 base = 0;
552     unsigned int datasize = 1;
553     int size = 256;
554     char *p;
555     bool valid_base = true;
556
557     
558     cyg_formdata_parse( formdata, formlist, 10 );
559
560     p = cyg_formlist_find( formlist, "base" );
561
562     /* If the page is requested without a 'base' parameter, do not attempt
563      * to access any memory locations to prevent illegal memory accesses
564      * on targets where '0' is not a valid address.
565      */
566     if( p != NULL )
567         sscanf( p, "%x", &base );
568     else
569         valid_base = false;
570
571     p = cyg_formlist_find( formlist, "datasize" );
572
573     if( p != NULL )
574         sscanf( p, "%x", &datasize );
575
576     if( cyg_formlist_find( formlist, "next" ) != NULL )
577         base += size;
578
579     if( cyg_formlist_find( formlist, "prev" ) != NULL )
580         base -= size;
581         
582     html_begin(client);
583
584     html_head(client,"eCos Memory Monitor", "");
585
586     html_body_begin(client,"");
587     {
588         html_heading(client, 2, "Memory Monitor" );
589
590         html_form_begin( client, "/monitor/memory.html", "" );
591         {
592
593             /* Text input control for base address
594              */
595             html_para_begin( client, "" );
596             fprintf(client,
597                     "Base Address: 0x<input type=\"text\" name=\"base\" size=\"10\" value=\"%x\">\n",
598                     base);
599
600             fprintf(client,
601                     "WARNING: entering an illegal base address can crash the system.\n");
602
603             /* A little menu for the element size
604              */
605             html_para_begin( client, "" );
606
607             fputs( "Element Size: ", client );
608             html_form_select_begin( client, "datasize", "" );
609             html_form_option( client, "1", "bytes", datasize==1 );
610             html_form_option( client, "2", "words", datasize==2 );
611             html_form_option( client, "4", "dwords", datasize==4 );
612             html_form_select_end( client );
613                         
614             html_para_begin( client, "" );
615
616             /* Submit and reset buttons
617              */
618             html_form_input(client, "submit", "submit", "Submit", "");                
619             html_form_input(client, "reset", "reset", "Reset", "");
620
621             html_para_begin( client, "" );
622
623             /* Previous page button */
624             html_form_input(client, "submit", "prev", "Prev Page", "");
625
626             /* Switch to monospaced font */
627             cyg_html_tag_begin( client, "font", "face=\"monospace\"" );
628             
629             html_table_begin( client, "" );
630
631             if (valid_base == true) {
632                 cyg_addrword_t loc;
633                 cyg_addrword_t oloc;
634                 
635                 for( oloc = loc = base; loc <= (base+size) ; loc++ )
636                 {
637                     if( ( loc % 16 ) == 0 )
638                     {
639                         if( loc != base )
640                         {
641                             html_table_data_begin( client, "" );
642                             for( ; oloc < loc; oloc++ )
643                             {
644                                 char c = *(char *)oloc;
645                                 if( !isprint(c) )
646                                     c = '.';
647                                 putc( c, client );
648                             }
649                             html_table_row_end( client );
650                         }
651                         if( loc == (base+size) )
652                             break;
653                         html_table_row_begin(client, "" );
654                         html_table_data_begin( client, "" );
655                         fprintf( client, "%08x:",loc);
656                     }
657
658                     html_table_data_begin( client, "" );
659
660                     if( (loc % datasize) == 0 )
661                     {
662                         switch( datasize )
663                         {
664                         case 1: fprintf( client, "%02x", *(cyg_uint8  *)loc ); break;
665                         case 2: fprintf( client, "%04x", *(cyg_uint16 *)loc ); break;
666                         case 4: fprintf( client, "%08x", *(cyg_uint32 *)loc ); break;
667                         }
668                     }
669                 }
670             }
671             html_table_end( client );
672             cyg_html_tag_end( client, "font" );
673             
674             html_form_input(client, "submit", "next", "Next Page", "");            
675         }
676         html_form_end( client );
677
678         draw_navbar(client);
679     }
680     html_body_end(client);
681
682     html_end(client);
683     
684     return 1;
685     
686 }
687
688 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_memory_entry,
689                        "/monitor/memory.htm*",
690                        cyg_monitor_memory,
691                        NULL );
692
693 /* ================================================================= */
694 /* Network Monitor
695  *
696  * This function generates a page containing information about the
697  * network interfaces and the protocols.
698  */
699
700 static cyg_bool cyg_monitor_network( FILE * client, char *filename,
701                                      char *formdata, void *arg )
702 {
703     struct ifaddrs *iflist, *ifp;
704
705     if(getifaddrs(&iflist)!=0)
706         return 0;
707     
708     html_begin(client);
709
710     html_head(client,"eCos Network Monitor", "");
711
712     html_body_begin(client,"");
713     {
714         html_heading(client, 2, "Network Monitor" );
715
716         html_heading(client, 3, "Interfaces" );        
717
718         html_table_begin( client, "border" );
719         {
720             char addr[64];
721             int i;
722             ifp = iflist;
723
724             html_table_header( client, "Interface", "" );
725             html_table_header( client, "Status", "" );
726
727             while( ifp != (struct ifaddrs *)NULL) 
728             {
729                 if (ifp->ifa_addr->sa_family != AF_LINK) 
730                 {
731                   
732                   html_table_row_begin(client, "" );
733                   {
734                         html_table_data_begin( client, "" );
735                         fprintf( client, "%s", ifp->ifa_name);
736
737                         html_table_data_begin( client, "" );                        
738                         html_table_begin( client, "" );
739                         {
740                             /* Get the interface's flags and display
741                              * the interesting ones.
742                              */
743                             
744                             html_table_row_begin(client, "" );
745                             fprintf( client, "<td>Flags<td>\n" );
746                             for( i = 0; i < 16; i++ )
747                               {
748                                 switch( ifp->ifa_flags & (1<<i) )
749                                   {
750                                   default: break;
751                                   case IFF_UP: fputs( " UP", client ); break;
752                                   case IFF_BROADCAST: fputs( " BROADCAST", client ); break;
753                                   case IFF_DEBUG: fputs( " DEBUG", client ); break;
754                                   case IFF_LOOPBACK: fputs( " LOOPBACK", client ); break;
755                                   case IFF_PROMISC: fputs( " PROMISCUOUS", client ); break;
756                                   case IFF_RUNNING: fputs( " RUNNING", client ); break;
757                                   case IFF_SIMPLEX: fputs( " SIMPLEX", client ); break;
758                                   case IFF_MULTICAST: fputs( " MULTICAST", client ); break;
759                                   }
760                               }
761                             html_table_row_end( client );                
762                             
763                             html_table_row_begin(client, "" );
764                             getnameinfo(ifp->ifa_addr, sizeof(*ifp->ifa_addr),
765                                         addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
766                             fprintf( client, "<td>Address<td>%s\n", addr);
767                             html_table_row_end( client );
768                             
769                             if (ifp->ifa_netmask) 
770                             {
771                               html_table_row_begin(client, "" );
772                               getnameinfo(ifp->ifa_netmask, sizeof(*ifp->ifa_netmask),
773                                           addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
774                               fprintf( client, "<td>Mask<td>%s\n", addr); 
775                               html_table_row_end( client );
776                             }
777
778                             if (ifp->ifa_broadaddr) 
779                             {
780                               html_table_row_begin(client, "" );
781                               getnameinfo(ifp->ifa_broadaddr, sizeof(*ifp->ifa_broadaddr),
782                                           addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
783                               fprintf( client, "<td>Broadcast<td>%s\n", addr); 
784                               html_table_row_end( client );
785                             }
786                         }
787                         html_table_end( client );   
788                     }
789                     html_table_row_end( client );
790
791                 }
792                 ifp = ifp->ifa_next;
793             }
794         }
795         html_table_end( client );
796
797         /* Now the protocols. For each of the main protocols: IP,
798          * ICMP, UDP, TCP print a table of useful information derived
799          * from the in-kernel data structures. Note that this only
800          * works for the BSD stacks.
801          */
802         
803         html_para_begin( client, "" );
804         html_heading(client, 3, "Protocols" );
805
806         html_para_begin( client, "" );
807         html_table_begin( client, "border");
808         {
809             html_table_header( client, "IPv4", "" );
810 #ifdef CYGPKG_NET_INET6
811             html_table_header( client, "IPv6", "" );
812 #endif            
813             html_table_header( client, "ICMPv4", "" );
814 #ifdef CYGPKG_NET_INET6
815             html_table_header( client, "ICMPv6", "" );
816 #endif            
817             html_table_header( client, "UDP", "" );
818             html_table_header( client, "TCP", "" );
819
820             html_table_row_begin(client, "" );
821             {
822                 html_table_data_begin( client, "valign=\"top\"" );                        
823                 html_table_begin( client, "" );
824                 {
825
826                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
827                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
828                              ipstat.ips_total );
829                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bad",
830                              ipstat.ips_badsum+
831                              ipstat.ips_tooshort+
832                              ipstat.ips_toosmall+
833                              ipstat.ips_badhlen+
834                              ipstat.ips_badlen+
835                              ipstat.ips_noproto+
836                              ipstat.ips_toolong
837                         );
838                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Reassembled",
839                              ipstat.ips_reassembled );
840                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Delivered",
841                              ipstat.ips_delivered );
842
843                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
844                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
845                              ipstat.ips_localout );
846                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Raw",
847                              ipstat.ips_rawout );
848                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Fragmented",
849                              ipstat.ips_fragmented );
850                 }
851                 html_table_end( client );
852 #ifdef CYGPKG_NET_INET6
853                 html_table_data_begin( client, "valign=\"top\"" );                        
854                 html_table_begin( client, "" );
855                 {
856
857                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
858                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Total",
859                              ip6stat.ip6s_total );
860                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Bad",
861                              ip6stat.ip6s_tooshort+
862                              ip6stat.ip6s_toosmall
863                         );
864                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Reassembled",
865                              ip6stat.ip6s_reassembled );
866                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Delivered",
867                              ip6stat.ip6s_delivered );
868
869                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
870                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Total",
871                              ip6stat.ip6s_localout );
872                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Raw",
873                              ip6stat.ip6s_rawout );
874                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Fragmented",
875                              ip6stat.ip6s_fragmented );
876                 }
877                 html_table_end( client );
878 #endif
879                 html_table_data_begin( client, "valign=\"top\"" );                        
880                 html_table_begin( client, "" );
881                 {
882
883                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
884                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO",
885                              icmpstat.icps_inhist[ICMP_ECHO] );
886                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO REPLY",
887                              icmpstat.icps_inhist[ICMP_ECHOREPLY] );
888                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "UNREACH",
889                              icmpstat.icps_inhist[ICMP_UNREACH] );
890                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "REDIRECT",
891                              icmpstat.icps_inhist[ICMP_REDIRECT] );
892                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Other",
893                              icmpstat.icps_inhist[ICMP_SOURCEQUENCH]+
894                              icmpstat.icps_inhist[ICMP_ROUTERADVERT]+
895                              icmpstat.icps_inhist[ICMP_ROUTERSOLICIT]+
896                              icmpstat.icps_inhist[ICMP_TIMXCEED]+
897                              icmpstat.icps_inhist[ICMP_PARAMPROB]+
898                              icmpstat.icps_inhist[ICMP_TSTAMP]+
899                              icmpstat.icps_inhist[ICMP_TSTAMPREPLY]+
900                              icmpstat.icps_inhist[ICMP_IREQ]+
901                              icmpstat.icps_inhist[ICMP_IREQREPLY]+
902                              icmpstat.icps_inhist[ICMP_MASKREQ]+
903                              icmpstat.icps_inhist[ICMP_MASKREPLY]
904                         );
905                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bad",
906                              icmpstat.icps_badcode+
907                              icmpstat.icps_tooshort+
908                              icmpstat.icps_checksum+
909                              icmpstat.icps_badlen+
910                              icmpstat.icps_bmcastecho
911                         );
912
913                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
914                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO",
915                              icmpstat.icps_outhist[ICMP_ECHO] );
916                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO REPLY",
917                              icmpstat.icps_outhist[ICMP_ECHOREPLY] );
918                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "UNREACH",
919                              icmpstat.icps_outhist[ICMP_UNREACH] );
920                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "REDIRECT",
921                              icmpstat.icps_outhist[ICMP_REDIRECT] );
922                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Other",
923                              icmpstat.icps_inhist[ICMP_SOURCEQUENCH]+                             
924                              icmpstat.icps_outhist[ICMP_ROUTERADVERT]+
925                              icmpstat.icps_outhist[ICMP_ROUTERSOLICIT]+
926                              icmpstat.icps_outhist[ICMP_TIMXCEED]+
927                              icmpstat.icps_outhist[ICMP_PARAMPROB]+
928                              icmpstat.icps_outhist[ICMP_TSTAMP]+
929                              icmpstat.icps_outhist[ICMP_TSTAMPREPLY]+
930                              icmpstat.icps_outhist[ICMP_IREQ]+
931                              icmpstat.icps_outhist[ICMP_IREQREPLY]+
932                              icmpstat.icps_outhist[ICMP_MASKREQ]+
933                              icmpstat.icps_outhist[ICMP_MASKREPLY]
934                         );
935                 }
936                 html_table_end( client );
937
938 #ifdef CYGPKG_NET_INET6
939                 html_table_data_begin( client, "valign=\"top\"" );                        
940                 html_table_begin( client, "" );
941                 {
942
943                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
944                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO",
945                              icmp6stat.icp6s_inhist[ICMP_ECHO] );
946                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO REPLY",
947                              icmp6stat.icp6s_inhist[ICMP_ECHOREPLY] );
948                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "UNREACH",
949                              icmp6stat.icp6s_inhist[ICMP_UNREACH] );
950                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "REDIRECT",
951                              icmp6stat.icp6s_inhist[ICMP_REDIRECT] );
952                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Other",
953                              icmp6stat.icp6s_inhist[ICMP_SOURCEQUENCH]+
954                              icmp6stat.icp6s_inhist[ICMP_ROUTERADVERT]+
955                              icmp6stat.icp6s_inhist[ICMP_ROUTERSOLICIT]+
956                              icmp6stat.icp6s_inhist[ICMP_TIMXCEED]+
957                              icmp6stat.icp6s_inhist[ICMP_PARAMPROB]+
958                              icmp6stat.icp6s_inhist[ICMP_TSTAMP]+
959                              icmp6stat.icp6s_inhist[ICMP_TSTAMPREPLY]+
960                              icmp6stat.icp6s_inhist[ICMP_IREQ]+
961                              icmp6stat.icp6s_inhist[ICMP_IREQREPLY]+
962                              icmp6stat.icp6s_inhist[ICMP_MASKREQ]+
963                              icmp6stat.icp6s_inhist[ICMP_MASKREPLY]
964                         );
965                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Bad",
966                              icmp6stat.icp6s_badcode+
967                              icmp6stat.icp6s_tooshort+
968                              icmp6stat.icp6s_checksum+
969                              icmp6stat.icp6s_badlen
970                         );
971
972                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
973                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO",
974                              icmp6stat.icp6s_outhist[ICMP_ECHO] );
975                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO REPLY",
976                              icmp6stat.icp6s_outhist[ICMP_ECHOREPLY] );
977                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "UNREACH",
978                              icmp6stat.icp6s_outhist[ICMP_UNREACH] );
979                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "REDIRECT",
980                              icmp6stat.icp6s_outhist[ICMP_REDIRECT] );
981                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Other",
982                              icmp6stat.icp6s_inhist[ICMP_SOURCEQUENCH]+                             
983                              icmp6stat.icp6s_outhist[ICMP_ROUTERADVERT]+
984                              icmp6stat.icp6s_outhist[ICMP_ROUTERSOLICIT]+
985                              icmp6stat.icp6s_outhist[ICMP_TIMXCEED]+
986                              icmp6stat.icp6s_outhist[ICMP_PARAMPROB]+
987                              icmp6stat.icp6s_outhist[ICMP_TSTAMP]+
988                              icmp6stat.icp6s_outhist[ICMP_TSTAMPREPLY]+
989                              icmp6stat.icp6s_outhist[ICMP_IREQ]+
990                              icmp6stat.icp6s_outhist[ICMP_IREQREPLY]+
991                              icmp6stat.icp6s_outhist[ICMP_MASKREQ]+
992                              icmp6stat.icp6s_outhist[ICMP_MASKREPLY]
993                         );
994                 }
995                 html_table_end( client );
996 #endif
997                 html_table_data_begin( client, "valign=\"top\"" );                        
998                 html_table_begin( client, "" );
999                 {
1000
1001                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
1002                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
1003                              udpstat.udps_ipackets );
1004                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bad",
1005                              udpstat.udps_hdrops+
1006                              udpstat.udps_badsum+
1007                              udpstat.udps_badlen+
1008                              udpstat.udps_noport+
1009                              udpstat.udps_noportbcast+
1010                              udpstat.udps_fullsock
1011                         );
1012                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
1013                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
1014                              udpstat.udps_opackets );
1015                 }
1016                 html_table_end( client );
1017
1018                 html_table_data_begin( client, "valign=\"top\"" );                        
1019                 html_table_begin( client, "" );
1020                 {
1021
1022                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Connections" );
1023                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Initiated",
1024                              tcpstat.tcps_connattempt );
1025                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Accepted",
1026                              tcpstat.tcps_accepts );
1027                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Established",
1028                              tcpstat.tcps_connects );
1029                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Closed",
1030                              tcpstat.tcps_closed );
1031
1032                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
1033                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Packets",
1034                              tcpstat.tcps_rcvtotal );
1035                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Data Packets",
1036                              tcpstat.tcps_rcvpack );
1037                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bytes",
1038                              tcpstat.tcps_rcvbyte );
1039                     
1040                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );
1041                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Packets",
1042                              tcpstat.tcps_sndtotal );
1043                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Data Packets",
1044                              tcpstat.tcps_sndpack );
1045                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bytes",
1046                              tcpstat.tcps_sndbyte );
1047
1048                     
1049                 }
1050                 html_table_end( client );
1051                 
1052                 
1053             }
1054             html_table_row_end( client );
1055
1056         }
1057         html_table_end( client );
1058
1059         html_para_begin( client, "" );
1060         html_heading(client, 3, "Mbufs" );
1061
1062         html_table_begin( client, "border" );
1063         {
1064             html_table_header( client, "Summary", "" );
1065             html_table_header( client, "Types", "" );
1066
1067             html_table_row_begin( client, "" );
1068             {
1069                 html_table_data_begin( client, "valign=\"top\"" );                        
1070                 html_table_begin( client, "" );
1071                 {
1072                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Mbufs",
1073                              mbstat.m_mbufs );
1074                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Clusters",
1075                              mbstat.m_clusters );
1076                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Free Clusters",
1077                              mbstat.m_clfree );
1078                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Drops",
1079                              mbstat.m_drops );
1080                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Waits",
1081                              mbstat.m_wait );
1082                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Drains",
1083                              mbstat.m_drain );
1084 #if defined(CYGPKG_NET_FREEBSD_STACK)
1085                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Copy Fails",
1086                              mbstat.m_mcfail );
1087                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Pullup Fails",
1088                              mbstat.m_mpfail );
1089 #endif                    
1090
1091                 }
1092                 html_table_end( client );
1093
1094                 html_table_data_begin( client, "valign=\"top\"" );                        
1095                 html_table_begin( client, "" );
1096                 {
1097                     u_long *mtypes;
1098 #if defined(CYGPKG_NET_FREEBSD_STACK)
1099                     mtypes = mbtypes;
1100 #else
1101                     mtypes = mbstat.m_mtypes;
1102 #endif
1103                     
1104                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "FREE",
1105                              mtypes[MT_FREE] );
1106                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "DATA",
1107                              mtypes[MT_DATA] );
1108                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "HEADER",
1109                              mtypes[MT_HEADER] );
1110 #if !defined(CYGPKG_NET_FREEBSD_STACK)                    
1111                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "SOCKET",
1112                              mtypes[MT_SOCKET] );
1113                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "PCB",
1114                              mtypes[MT_PCB] );
1115                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "RTABLE",
1116                              mtypes[MT_RTABLE] );
1117                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "HTABLE",
1118                              mtypes[MT_HTABLE] );
1119                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ATABLE",
1120                              mtypes[MT_ATABLE] );
1121 #endif
1122                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "SONAME",
1123                              mtypes[MT_SONAME] );
1124 #if !defined(CYGPKG_NET_FREEBSD_STACK)                                        
1125                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "SOOPTS",
1126                              mtypes[MT_SOOPTS] );
1127 #endif
1128                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "FTABLE",
1129                              mtypes[MT_FTABLE] );
1130
1131                     /* Ignore the rest for now... */
1132                     
1133                 }
1134                 html_table_end( client );
1135                 
1136             }
1137             html_table_row_end( client );
1138             
1139         }
1140         html_table_end( client );
1141         
1142         
1143         draw_navbar(client);
1144     }
1145     html_body_end(client);
1146
1147     html_end(client);
1148     
1149     freeifaddrs(iflist);
1150     return 1;
1151     
1152 }
1153
1154 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_network_entry,
1155                        "/monitor/network.htm*",
1156                        cyg_monitor_network,
1157                        NULL );
1158
1159         
1160 /* ================================================================= */
1161 /* Instrumentation Monitor
1162  *
1163  * If the CYGPKG_KERNEL_INSTRUMENT option is set, we generate a table
1164  * showing the current instrumentation buffer. If the FLAGS option is
1165  * enabled we also print a table giving control of the flags.
1166  * 
1167  */
1168
1169 #ifdef CYGPKG_KERNEL_INSTRUMENT
1170
1171 /* Instrumentation record. */
1172 struct Instrument_Record
1173 {
1174     CYG_WORD16  type;                   // record type
1175     CYG_WORD16  thread;                 // current thread id
1176     CYG_WORD    timestamp;              // 32 bit timestamp
1177     CYG_WORD    arg1;                   // first arg
1178     CYG_WORD    arg2;                   // second arg
1179 };
1180 typedef struct Instrument_Record Instrument_Record;
1181
1182 /* Instrumentation variables, these live in the
1183  * instrumentation files in the kernel
1184  */
1185 __externC Instrument_Record       *instrument_buffer_pointer;
1186 __externC Instrument_Record       instrument_buffer[];
1187 __externC cyg_uint32              instrument_buffer_size;
1188
1189 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1190     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1191
1192 static cyg_uint32 instrument_flags[(CYG_INSTRUMENT_CLASS_MAX>>8)+1];
1193
1194 #endif
1195
1196 static char cyg_monitor_instrument_blurb1[] =
1197 "<p>Use the checkboxes to enable the events to be recorded. Click "
1198 "the <em>Submit</em> button to start recording. Click the <em>Clear</em> "
1199 "button to clear all instrumentation and to stop recording."
1200 ;
1201
1202 static cyg_bool cyg_monitor_instrument( FILE * client, char *filename,
1203                                         char *formdata, void *arg )
1204 {
1205
1206 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1207     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1208
1209     /* Disable all instrumentation while we generate the page.
1210      * Otherwise we could swamp the information we are really after.
1211      */
1212     
1213     cyg_scheduler_lock();
1214     {
1215         struct instrument_desc_s *id = instrument_desc;
1216         CYG_WORD cl = 0, ev = 0;
1217
1218         for( ; id->msg != 0; id++ )
1219         {
1220             if( id->num > 0xff )
1221             {
1222                 cl = id->num>>8;
1223                 instrument_flags[cl] = 0;
1224             }
1225             else
1226             {
1227                 ev = id->num;
1228                 cyg_instrument_disable( cl<<8, ev );
1229             }
1230         }
1231     }
1232     cyg_scheduler_unlock();
1233
1234 #endif
1235     
1236     /* If we have some form data, deal with it.
1237      */
1238     if( formdata != NULL )
1239     {
1240         char *list[40];
1241         
1242         cyg_formdata_parse( formdata, list, sizeof(list)/sizeof(*list) );
1243
1244 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1245     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1246         
1247         if( cyg_formlist_find( list, "clear" ) != NULL )
1248         {
1249             /* If the clear button is set, then disable all instrumentation flags.
1250              */
1251             int i;
1252             for( i = 0; i < sizeof(instrument_flags)/sizeof(*instrument_flags); i++ )
1253                 instrument_flags[i] = 0;
1254         }
1255         else
1256         {
1257             /* Otherwise all the set checkboxes have been reported to
1258              * us in the form of class=event inputs.
1259              */
1260             char **p;
1261             for( p = list; *p != NULL; p++ )
1262             {
1263                 int cl,ev;
1264                 if( sscanf( *p, "%02x=%02x", &cl, &ev ) == 2 )
1265                     instrument_flags[cl] |= 1<<ev;
1266             }
1267         }
1268 #endif
1269         
1270         /* If the cleartable button has been pressed, clear all the
1271          * table entries. 
1272          */
1273         if( cyg_formlist_find( list, "cleartable" ) != NULL )
1274         {
1275             cyg_scheduler_lock();
1276             {
1277                 Instrument_Record *ibp = instrument_buffer_pointer;
1278                 do
1279                 {
1280                     ibp->type = 0;
1281                     ibp++;
1282                     if( ibp == &instrument_buffer[instrument_buffer_size] )
1283                         ibp = instrument_buffer;
1284                     
1285                 } while( ibp != instrument_buffer_pointer );
1286                 
1287             }
1288             cyg_scheduler_unlock();
1289         }
1290     }
1291     
1292     /* Now start generating the HTML page.
1293      */
1294     html_begin(client);
1295
1296     html_head(client,"eCos Instrumentation Buffer", "");
1297
1298     html_body_begin(client,"");
1299     {
1300         html_heading(client, 2, "Instrumentation Buffer" );
1301
1302         html_form_begin( client, "/monitor/instrument.html", "" );
1303         
1304 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1305     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1306         
1307         /* If we have the flags enabled, generate a table showing all
1308          * the flag names with a checkbox against each.
1309          */
1310
1311         fputs( cyg_monitor_instrument_blurb1, client );
1312         
1313         html_para_begin( client, "" );        
1314         /* Add submit,clear and reset buttons */
1315         html_form_input(client, "submit", "submit", "Submit", "");                
1316         html_form_input(client, "submit", "clear", "Clear", "");                
1317         html_form_input(client, "reset", "reset", "Reset", "");
1318         
1319         html_table_begin( client, "border width=100%" );
1320         {
1321             struct instrument_desc_s *id = instrument_desc;
1322             CYG_WORD cl = 0, ev = 0;
1323             int clc = 0;
1324             char class[5], event[5];
1325
1326             html_table_row_begin( client, "" );
1327
1328             for( ; id->msg != 0; id++ )
1329             {
1330                 if( id->num > 0xff )
1331                 {
1332                     cl = id->num;
1333                     sprintf( class, "%02x", cl>>8 );
1334                     clc = 0;
1335                     
1336                     if( id != instrument_desc )
1337                     {
1338                         html_table_end( client );
1339                         html_table_row_end( client );
1340                         html_table_row_begin( client, "" );
1341                     }
1342                         
1343                     html_table_data_begin( client, "valign=\"top\" width=100%" );
1344                     html_table_begin( client, "width=100%" );
1345                 }
1346                 else
1347                 {
1348                     ev = id->num;
1349                     sprintf( event, "%02x", ev );
1350
1351                     if( (clc%4) == 0 )
1352                     {
1353                         if( clc != 0 )
1354                             html_table_row_end( client );
1355
1356                         html_table_row_begin( client, "" );
1357                     }
1358                     clc++;
1359                     html_table_data_begin( client, "width=25%" );
1360                     html_form_input_checkbox( client, class, event,
1361                                               instrument_flags[cl>>8] & (1<<ev) );
1362                     fputs( id->msg, client );
1363                 }
1364             }            
1365             html_table_end( client );
1366             html_table_row_end( client );
1367         }
1368         html_table_end( client );
1369
1370         /* Add submit,clear and reset buttons */
1371         html_form_input(client, "submit", "submit", "Submit", "");                
1372         html_form_input(client, "submit", "clear", "Clear", "");                
1373         html_form_input(client, "reset", "reset", "Reset", "");
1374
1375 #endif
1376
1377         html_para_begin( client, "" );
1378
1379         html_form_input(client, "submit", "cleartable", "Clear Table", "");
1380
1381         
1382         /*
1383          */
1384         
1385         html_table_begin( client, "border" );
1386         {
1387             Instrument_Record *ibp = instrument_buffer_pointer;
1388
1389             html_table_header( client, "TIME", "" );
1390             html_table_header( client, "THREAD", "" );
1391             html_table_header( client, "EVENT", "" );
1392             html_table_header( client, "ARG1", "" );
1393             html_table_header( client, "ARG2", "" );
1394
1395             do
1396             {
1397                 if( ibp->type != 0 )
1398                 {
1399                     html_table_row_begin(client, "" );
1400                     {
1401                         cyg_handle_t thread = cyg_thread_find(ibp->thread);
1402                         cyg_thread_info info;
1403                     
1404                         html_table_data_begin( client, "" );
1405                         fprintf( client, "%08x",ibp->timestamp);
1406                         html_table_data_begin( client, "" );
1407                         if( thread != 0 &&
1408                             cyg_thread_get_info( thread, ibp->thread, &info ) &&
1409                             info.name != NULL )
1410                             fputs( info.name, client );
1411                         else fprintf( client, "[%04x]", ibp->thread);
1412                         html_table_data_begin( client, "" );
1413 #if defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1414                         fprintf( client, "%s", cyg_instrument_msg(ibp->type));
1415 #else
1416                         fprintf( client, "%04x", ibp->type );
1417 #endif
1418                         html_table_data_begin( client, "" );
1419                         fprintf( client, "%08x", ibp->arg1);
1420                         html_table_data_begin( client, "" );
1421                         fprintf( client, "%08x", ibp->arg2);
1422                     }
1423                     html_table_row_end( client );
1424                 }
1425                 ibp++;
1426                 if( ibp == &instrument_buffer[instrument_buffer_size] )
1427                     ibp = instrument_buffer;
1428                 
1429             } while( ibp != instrument_buffer_pointer );
1430         }
1431         html_table_end( client );
1432
1433         html_para_begin( client, "" );
1434
1435         html_form_input(client, "submit", "cleartable", "Clear Table", "");
1436         
1437         html_form_end( client );
1438         
1439         draw_navbar(client);
1440     }
1441     html_body_end(client);
1442
1443     html_end(client);
1444
1445
1446 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1447     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1448
1449     /*
1450      */
1451
1452     cyg_scheduler_lock();
1453     {
1454         struct instrument_desc_s *id = instrument_desc;
1455         CYG_WORD cl = 0, ev = 0;
1456
1457         for( ; id->msg != 0; id++ )
1458         {
1459             if( id->num > 0xff )
1460                 cl = id->num>>8;
1461             else
1462             {
1463                 ev = id->num;
1464                 if( (instrument_flags[cl] & (1<<ev)) != 0 )
1465                     cyg_instrument_enable( cl<<8, ev );
1466             }
1467         }
1468     }
1469     cyg_scheduler_unlock();
1470 #endif
1471     
1472     return true;
1473 }
1474
1475 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_instrument_entry,
1476                        "/monitor/instrument.htm*",
1477                        cyg_monitor_instrument,
1478                        NULL );
1479
1480 #endif
1481
1482 /* ================================================================= */
1483 /* eCos Logo
1484  *
1485  * Define the logo as a byte array, and then define the data structure
1486  * and table entry to allow it to be fetched by the client.
1487  */
1488
1489 static cyg_uint8 ecos_logo_gif[] = {
1490     0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x6f, 0x00, 0x23, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00,
1491     0xff, 0xff, 0xff, 0xea, 0x19, 0x00, 0xcc, 0x00, 0x00, 0xfd, 0xfd, 0xfd, 0x83, 0x00, 0x00, 0xf6,
1492     0xf6, 0xf6, 0x2f, 0x2f, 0x2f, 0xef, 0xef, 0xef, 0x19, 0x00, 0x19, 0x45, 0x45, 0x45, 0xbb, 0xbb,
1493     0xbb, 0xe2, 0x3e, 0x3e, 0xe8, 0xbb, 0xd3, 0x3e, 0x3e, 0x3e, 0xfb, 0xfb, 0xfb, 0xbe, 0xbe, 0xbe,
1494     0xf1, 0xed, 0xed, 0xe5, 0x7b, 0x8e, 0xe5, 0x6b, 0x7b, 0xcc, 0xcc, 0xcc, 0x98, 0x95, 0x98, 0xc6,
1495     0xc3, 0xc6, 0x19, 0x19, 0x19, 0xf1, 0xf1, 0xf1, 0x98, 0x98, 0x98, 0xd6, 0xd3, 0xd6, 0x83, 0x83,
1496     0x83, 0xde, 0xde, 0xde, 0xe5, 0x25, 0x25, 0x73, 0x6f, 0x73, 0xea, 0xea, 0xea, 0xe5, 0x8e, 0xa2,
1497     0xe8, 0xe8, 0xe8, 0x7f, 0x7b, 0x7f, 0xe2, 0x56, 0x66, 0x8b, 0x8b, 0x8b, 0x19, 0x19, 0x00, 0xf8,
1498     0xf8, 0xf8, 0x73, 0x73, 0x73, 0xd3, 0xd1, 0xd1, 0x9c, 0x9c, 0x9c, 0x50, 0x50, 0x50, 0xef, 0xce,
1499     0xea, 0x92, 0x8e, 0x92, 0x6f, 0x6f, 0x6f, 0xe2, 0x2f, 0x2f, 0x61, 0x61, 0x61, 0xe5, 0xe5, 0xe5,
1500     0xe8, 0x9f, 0xb8, 0x37, 0x2f, 0x37, 0x66, 0x66, 0x66, 0xe2, 0x4b, 0x50, 0x56, 0x50, 0x56, 0xa9,
1501     0xa5, 0xa9, 0xce, 0xce, 0xce, 0x56, 0x50, 0x50, 0xd9, 0xd9, 0xd9, 0x77, 0x73, 0x77, 0x25, 0x25,
1502     0x2f, 0x6b, 0x6b, 0x6b, 0x9f, 0x9f, 0x9f, 0x87, 0x83, 0x87, 0x3e, 0x37, 0x37, 0xf4, 0xf4, 0xf4,
1503     0x25, 0x25, 0x25, 0xc1, 0xc1, 0xc1, 0x83, 0x7f, 0x83, 0xe5, 0xe2, 0xe2, 0x4b, 0x45, 0x4b, 0xd1,
1504     0xce, 0xd1, 0xaf, 0xac, 0xaf, 0xcc, 0xc9, 0xcc, 0x5b, 0x56, 0x5b, 0xdb, 0xd9, 0xdb, 0x66, 0x61,
1505     0x66, 0xe2, 0xe2, 0xe2, 0xb8, 0xb5, 0xb8, 0x2f, 0x25, 0x2f, 0xc3, 0xc1, 0xc3, 0xe0, 0xde, 0xe0,
1506     0xd3, 0xd3, 0xd3, 0xde, 0xdb, 0xde, 0xac, 0xac, 0xac, 0xce, 0xcc, 0xce, 0x77, 0x6f, 0x73, 0x4b,
1507     0x45, 0x45, 0xc9, 0xc6, 0xc9, 0x45, 0x3e, 0x45, 0x61, 0x5b, 0x61, 0xb5, 0xb2, 0xb5, 0x3e, 0x00,
1508     0x00, 0x8b, 0x87, 0x87, 0x95, 0x92, 0x95, 0xa2, 0x9f, 0xa2, 0xb8, 0xb8, 0xb8, 0x7b, 0x77, 0x7b,
1509     0x9c, 0x98, 0x9c, 0x50, 0x4b, 0x50, 0x6f, 0x6b, 0x6f, 0x6b, 0x66, 0x6b, 0xac, 0xa9, 0xac, 0x8e,
1510     0x8b, 0x8e, 0x8e, 0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xed, 0xed, 0xed, 0x50, 0x4b, 0x4b, 0x3e, 0x37,
1511     0x3e, 0x95, 0x95, 0x95, 0xa5, 0xa2, 0xa5, 0x9f, 0x9c, 0x9f, 0xc1, 0xbe, 0xbe, 0x2f, 0x25, 0x25,
1512     0xd3, 0xd1, 0xd3, 0xf4, 0xf1, 0xf4, 0xc6, 0xc6, 0xc6, 0x8e, 0x8e, 0x8e, 0x25, 0x19, 0x19, 0x66,
1513     0x61, 0x61, 0xb2, 0xaf, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1514     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1515     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1516     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1517     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1518     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1519     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1520     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1521     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1522     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1523     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1524     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1525     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1526     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1527     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1528     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1529     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1530     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1531     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1532     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1533     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1534     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1535     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1536     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1537     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1538     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2c, 0x00, 0x00,
1539     0x00, 0x00, 0x6f, 0x00, 0x23, 0x00, 0x40, 0x08, 0xff, 0x00, 0x03, 0x08, 0x1c, 0x28, 0x10, 0x41,
1540     0x8a, 0x17, 0x0e, 0x1c, 0x00, 0x58, 0xc8, 0xb0, 0xa1, 0xc3, 0x87, 0x10, 0x21, 0x12, 0x14, 0x28,
1541     0xa0, 0xa2, 0xc5, 0x8b, 0x18, 0x33, 0x6a, 0xdc, 0xb8, 0x91, 0x01, 0x83, 0x11, 0x31, 0x26, 0x12,
1542     0x44, 0x10, 0x91, 0xe1, 0x09, 0x91, 0x28, 0x03, 0x4c, 0xb9, 0x50, 0x72, 0xa1, 0x0a, 0x04, 0x29,
1543     0x09, 0x72, 0x6c, 0x10, 0x73, 0xe2, 0x88, 0x8d, 0x2e, 0x0c, 0xd4, 0x0c, 0x70, 0x73, 0x63, 0x80,
1544     0x88, 0x10, 0x76, 0x0a, 0x6d, 0x18, 0x94, 0x60, 0x03, 0x8e, 0x1a, 0x27, 0x4a, 0x40, 0x5a, 0x51,
1545     0xa9, 0xc5, 0x0e, 0x3b, 0x0d, 0x30, 0x40, 0xca, 0x40, 0x45, 0xc9, 0x14, 0x42, 0x45, 0x72, 0x60,
1546     0xf9, 0xf0, 0x64, 0xd6, 0x00, 0x19, 0x3b, 0xe8, 0xfc, 0x3a, 0x70, 0xe9, 0x45, 0x10, 0x59, 0x0d,
1547     0x70, 0x9c, 0x30, 0xf1, 0x44, 0xcb, 0xb7, 0x70, 0x4b, 0x8a, 0x64, 0x4a, 0xb7, 0xae, 0x5d, 0x01,
1548     0x6c, 0x51, 0xbe, 0x88, 0xcb, 0xb7, 0xef, 0xc2, 0xb9, 0x77, 0x03, 0x0b, 0xbe, 0x98, 0x37, 0xc0,
1549     0x81, 0x88, 0x58, 0x09, 0xde, 0xe0, 0xea, 0xf0, 0xc5, 0x44, 0x0e, 0x0f, 0x13, 0x13, 0x34, 0x30,
1550     0x21, 0x23, 0xdb, 0x8c, 0x63, 0x07, 0x4a, 0xcd, 0x88, 0xd6, 0xa9, 0x45, 0x9a, 0x04, 0x69, 0x60,
1551     0xec, 0xc0, 0x94, 0x41, 0x44, 0xaf, 0x03, 0x53, 0xf8, 0xdd, 0xd1, 0x10, 0xf5, 0xc0, 0xa9, 0x76,
1552     0x41, 0x0f, 0x24, 0xcd, 0xb1, 0xf3, 0xc0, 0x9e, 0x1c, 0x25, 0x88, 0xac, 0xac, 0x91, 0x41, 0x00,
1553     0xc8, 0x6f, 0x77, 0x48, 0x9e, 0x78, 0xc3, 0xaa, 0xdf, 0x03, 0x27, 0xa6, 0x40, 0x28, 0x2a, 0x13,
1554     0xe9, 0x08, 0xd9, 0x93, 0x41, 0xd0, 0xe6, 0xd8, 0x41, 0x42, 0x83, 0x15, 0x02, 0x0d, 0x34, 0xe0,
1555     0x8d, 0x34, 0x73, 0x6a, 0xc6, 0x7e, 0xc3, 0x3b, 0xff, 0x04, 0x3c, 0xb8, 0x3c, 0x5d, 0xdb, 0x03,
1556     0xb7, 0xc2, 0x7d, 0x91, 0x02, 0xa6, 0xe2, 0x13, 0xe0, 0xf9, 0x22, 0x3f, 0xe1, 0x9a, 0x22, 0xd3,
1557     0x09, 0xd0, 0x03, 0x18, 0x00, 0x01, 0x9b, 0x2e, 0x48, 0xec, 0x01, 0x34, 0x10, 0xc3, 0x04, 0xd3,
1558     0x69, 0xa4, 0xd3, 0x5e, 0x11, 0x39, 0x46, 0x96, 0x40, 0x53, 0x44, 0xa4, 0x02, 0x59, 0x1a, 0xe5,
1559     0x97, 0x95, 0x68, 0x17, 0xd1, 0x80, 0x92, 0x77, 0xfd, 0x69, 0x34, 0x81, 0x83, 0x6d, 0x25, 0xe4,
1560     0xe1, 0x87, 0x0e, 0x3c, 0x48, 0x90, 0x6a, 0x0c, 0x89, 0x48, 0x10, 0x77, 0x74, 0x85, 0x44, 0x10,
1561     0x6e, 0x11, 0x4e, 0xd4, 0x9f, 0x84, 0x2b, 0x10, 0x68, 0x97, 0x69, 0x10, 0x31, 0x27, 0xd0, 0x72,
1562     0x38, 0xe6, 0xa8, 0x63, 0x8e, 0x44, 0x4d, 0x74, 0xd4, 0x5d, 0x13, 0xa1, 0xe8, 0x13, 0x41, 0x31,
1563     0x60, 0xe4, 0x02, 0x7a, 0x22, 0xa9, 0xd5, 0xd1, 0x61, 0x35, 0x4e, 0x84, 0x80, 0x42, 0x0e, 0x5d,
1564     0x70, 0x83, 0x48, 0xac, 0xf5, 0xe8, 0xa3, 0x46, 0x2e, 0xac, 0x30, 0x9a, 0x48, 0x45, 0x66, 0xc4,
1565     0x80, 0x77, 0x01, 0x74, 0x69, 0x91, 0x75, 0x05, 0x0a, 0x80, 0xa4, 0x59, 0x5e, 0x92, 0x54, 0x92,
1566     0x94, 0x5f, 0x3d, 0xf9, 0x16, 0x09, 0x59, 0x6d, 0x44, 0x03, 0x98, 0x31, 0xfd, 0x48, 0x58, 0x56,
1567     0x20, 0x20, 0x45, 0x90, 0x71, 0xe2, 0xf5, 0x39, 0xde, 0x44, 0xe6, 0x05, 0xea, 0xdf, 0x4e, 0x1c,
1568     0x90, 0xe0, 0x40, 0x95, 0x7e, 0xf2, 0x45, 0x9e, 0xa0, 0xe6, 0x75, 0xc0, 0x80, 0x04, 0x00, 0x0a,
1569     0x85, 0x00, 0x82, 0x89, 0x86, 0xb7, 0x28, 0xa3, 0x82, 0x4e, 0x40, 0x27, 0x41, 0x94, 0x56, 0x2a,
1570     0xde, 0xa5, 0x98, 0x32, 0x5a, 0x58, 0x6a, 0x7d, 0xed, 0x90, 0x10, 0x93, 0x9e, 0x02, 0x00, 0x2a,
1571     0x47, 0x2e, 0x78, 0x14, 0x2a, 0x53, 0xb6, 0x75, 0xff, 0x0a, 0x91, 0x03, 0x53, 0xc6, 0x84, 0x00,
1572     0x09, 0x7c, 0x5d, 0x70, 0x82, 0x7b, 0x29, 0x21, 0x25, 0xc1, 0xa6, 0x03, 0x35, 0x90, 0x61, 0x46,
1573     0x2e, 0x48, 0x18, 0xec, 0xb0, 0x16, 0xb1, 0x45, 0x62, 0x44, 0x70, 0x92, 0xb5, 0x58, 0x49, 0x0a,
1574     0x0a, 0xb5, 0x91, 0xb1, 0x31, 0xa1, 0x79, 0x11, 0xb5, 0x03, 0x69, 0xc9, 0x51, 0x0c, 0x50, 0x3e,
1575     0x74, 0x01, 0xaf, 0x05, 0x9d, 0x80, 0xaa, 0x0a, 0x36, 0x0a, 0x24, 0x2b, 0x00, 0xdf, 0xa2, 0xb4,
1576     0x82, 0x04, 0x13, 0x4c, 0x00, 0x02, 0x80, 0x96, 0xa1, 0xb4, 0x5d, 0xbb, 0x20, 0xd0, 0xa9, 0xe4,
1577     0x98, 0x3e, 0xd2, 0x46, 0x43, 0x03, 0x76, 0x76, 0x24, 0x17, 0x41, 0xea, 0x31, 0x3b, 0x11, 0x9f,
1578     0xe8, 0xa2, 0xe4, 0xc2, 0x46, 0x2c, 0x0a, 0x30, 0xc2, 0x44, 0x06, 0x1c, 0xac, 0x21, 0xc3, 0xd7,
1579     0x4e, 0x24, 0xe6, 0x8c, 0x02, 0x2f, 0xe8, 0x64, 0x43, 0xcd, 0x36, 0x67, 0xd7, 0x44, 0xda, 0x72,
1580     0x64, 0x21, 0x41, 0x68, 0xea, 0x96, 0xd2, 0x76, 0x74, 0xd1, 0xf8, 0x50, 0xb9, 0x16, 0xff, 0xc4,
1581     0x50, 0xb9, 0xfd, 0x32, 0xe5, 0x42, 0x90, 0x74, 0x5d, 0x69, 0xd1, 0xc2, 0x3b, 0x21, 0x6b, 0x91,
1582     0xc9, 0x0e, 0x65, 0x2c, 0x10, 0xaa, 0xe2, 0x4d, 0xc1, 0x71, 0x60, 0x32, 0xb3, 0xea, 0x59, 0x46,
1583     0x20, 0x6d, 0x6a, 0xb3, 0x00, 0x38, 0x37, 0xb4, 0x83, 0x48, 0xdd, 0x46, 0x09, 0x62, 0x42, 0x4a,
1584     0x8b, 0xd4, 0x31, 0xb1, 0x18, 0x89, 0x1c, 0x2c, 0x47, 0xbe, 0x01, 0x7a, 0xde, 0xd0, 0x18, 0x31,
1585     0xd0, 0x74, 0x43, 0x0e, 0xa0, 0x34, 0x85, 0x0a, 0x87, 0x39, 0x40, 0x02, 0xb8, 0x02, 0xe1, 0xea,
1586     0x50, 0xd8, 0x49, 0x4a, 0x00, 0x1b, 0x0d, 0x9d, 0x71, 0x96, 0xe4, 0x04, 0x53, 0x75, 0x00, 0x37,
1587     0x4a, 0x05, 0x42, 0xa5, 0x9f, 0xdb, 0x15, 0x8d, 0x61, 0x2a, 0xd0, 0xd1, 0x0c, 0x2c, 0x0b, 0x51,
1588     0xad, 0x6d, 0xf2, 0xec, 0xd0, 0x70, 0x35, 0x61, 0x69, 0x71, 0xcb, 0x7a, 0x0b, 0x65, 0x2d, 0x46,
1589     0x21, 0x11, 0x0c, 0x91, 0xce, 0x29, 0x41, 0x80, 0x68, 0x4b, 0x0e, 0xa0, 0xac, 0x35, 0x96, 0xd8,
1590     0x96, 0xd5, 0x51, 0xe7, 0x8f, 0x63, 0x44, 0x73, 0x00, 0x6e, 0xc5, 0xa5, 0x02, 0x09, 0xa8, 0x93,
1591     0xf0, 0xc2, 0xe5, 0x7e, 0xae, 0x1a, 0xd6, 0x08, 0x12, 0xc4, 0x2e, 0x01, 0x85, 0xaf, 0x66, 0x64,
1592     0x75, 0x41, 0x5f, 0xa7, 0xaa, 0xe8, 0xe6, 0xb5, 0x0b, 0x3a, 0x3a, 0x4a, 0x37, 0xe4, 0xae, 0xfb,
1593     0xbf, 0x1a, 0xf7, 0x3e, 0x18, 0x0d, 0x91, 0x0e, 0x14, 0x10, 0x00, 0x3b
1594 };
1595
1596 CYG_HTTPD_DATA( cyg_monitor_ecos_logo_data,
1597                 "image/gif",
1598                 sizeof(ecos_logo_gif), ecos_logo_gif );
1599
1600 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_ecos_logo,
1601                        "/monitor/ecos.gif",
1602                        cyg_httpd_send_data,
1603                        &cyg_monitor_ecos_logo_data );
1604
1605 /*------------------------------------------------------------------ */
1606 /* end of monitor.c                                                  */