]> git.karo-electronics.de Git - karo-tx-redboot.git/blob - packages/net/httpd/v2_0/src/monitor.c
eaad6b4e7fc3b871f32754f462f5bd500d25556d
[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     getifaddrs(&iflist);
706     
707     html_begin(client);
708
709     html_head(client,"eCos Network Monitor", "");
710
711     html_body_begin(client,"");
712     {
713         html_heading(client, 2, "Network Monitor" );
714
715         html_heading(client, 3, "Interfaces" );        
716
717         html_table_begin( client, "border" );
718         {
719             char addr[64];
720             int i;
721             ifp = iflist;
722
723             html_table_header( client, "Interface", "" );
724             html_table_header( client, "Status", "" );
725
726             while( ifp != (struct ifaddrs *)NULL) 
727             {
728                 if (ifp->ifa_addr->sa_family != AF_LINK) 
729                 {
730                   
731                   html_table_row_begin(client, "" );
732                   {
733                         html_table_data_begin( client, "" );
734                         fprintf( client, "%s", ifp->ifa_name);
735
736                         html_table_data_begin( client, "" );                        
737                         html_table_begin( client, "" );
738                         {
739                             /* Get the interface's flags and display
740                              * the interesting ones.
741                              */
742                             
743                             html_table_row_begin(client, "" );
744                             fprintf( client, "<td>Flags<td>\n" );
745                             for( i = 0; i < 16; i++ )
746                               {
747                                 switch( ifp->ifa_flags & (1<<i) )
748                                   {
749                                   default: break;
750                                   case IFF_UP: fputs( " UP", client ); break;
751                                   case IFF_BROADCAST: fputs( " BROADCAST", client ); break;
752                                   case IFF_DEBUG: fputs( " DEBUG", client ); break;
753                                   case IFF_LOOPBACK: fputs( " LOOPBACK", client ); break;
754                                   case IFF_PROMISC: fputs( " PROMISCUOUS", client ); break;
755                                   case IFF_RUNNING: fputs( " RUNNING", client ); break;
756                                   case IFF_SIMPLEX: fputs( " SIMPLEX", client ); break;
757                                   case IFF_MULTICAST: fputs( " MULTICAST", client ); break;
758                                   }
759                               }
760                             html_table_row_end( client );                
761                             
762                             html_table_row_begin(client, "" );
763                             getnameinfo(ifp->ifa_addr, sizeof(*ifp->ifa_addr),
764                                         addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
765                             fprintf( client, "<td>Address<td>%s\n", addr);
766                             html_table_row_end( client );
767                             
768                             if (ifp->ifa_netmask) 
769                             {
770                               html_table_row_begin(client, "" );
771                               getnameinfo(ifp->ifa_netmask, sizeof(*ifp->ifa_netmask),
772                                           addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
773                               fprintf( client, "<td>Mask<td>%s\n", addr); 
774                               html_table_row_end( client );
775                             }
776
777                             if (ifp->ifa_broadaddr) 
778                             {
779                               html_table_row_begin(client, "" );
780                               getnameinfo(ifp->ifa_broadaddr, sizeof(*ifp->ifa_broadaddr),
781                                           addr, sizeof(addr), NULL, 0, NI_NUMERICHOST);
782                               fprintf( client, "<td>Broadcast<td>%s\n", addr); 
783                               html_table_row_end( client );
784                             }
785                         }
786                         html_table_end( client );   
787                     }
788                     html_table_row_end( client );
789
790                 }
791                 ifp = ifp->ifa_next;
792             }
793         }
794         html_table_end( client );
795
796         /* Now the protocols. For each of the main protocols: IP,
797          * ICMP, UDP, TCP print a table of useful information derived
798          * from the in-kernel data structures. Note that this only
799          * works for the BSD stacks.
800          */
801         
802         html_para_begin( client, "" );
803         html_heading(client, 3, "Protocols" );
804
805         html_para_begin( client, "" );
806         html_table_begin( client, "border");
807         {
808             html_table_header( client, "IPv4", "" );
809 #ifdef CYGPKG_NET_INET6
810             html_table_header( client, "IPv6", "" );
811 #endif            
812             html_table_header( client, "ICMPv4", "" );
813 #ifdef CYGPKG_NET_INET6
814             html_table_header( client, "ICMPv6", "" );
815 #endif            
816             html_table_header( client, "UDP", "" );
817             html_table_header( client, "TCP", "" );
818
819             html_table_row_begin(client, "" );
820             {
821                 html_table_data_begin( client, "valign=\"top\"" );                        
822                 html_table_begin( client, "" );
823                 {
824
825                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
826                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
827                              ipstat.ips_total );
828                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bad",
829                              ipstat.ips_badsum+
830                              ipstat.ips_tooshort+
831                              ipstat.ips_toosmall+
832                              ipstat.ips_badhlen+
833                              ipstat.ips_badlen+
834                              ipstat.ips_noproto+
835                              ipstat.ips_toolong
836                         );
837                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Reassembled",
838                              ipstat.ips_reassembled );
839                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Delivered",
840                              ipstat.ips_delivered );
841
842                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
843                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
844                              ipstat.ips_localout );
845                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Raw",
846                              ipstat.ips_rawout );
847                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Fragmented",
848                              ipstat.ips_fragmented );
849                 }
850                 html_table_end( client );
851 #ifdef CYGPKG_NET_INET6
852                 html_table_data_begin( client, "valign=\"top\"" );                        
853                 html_table_begin( client, "" );
854                 {
855
856                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
857                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Total",
858                              ip6stat.ip6s_total );
859                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Bad",
860                              ip6stat.ip6s_tooshort+
861                              ip6stat.ip6s_toosmall
862                         );
863                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Reassembled",
864                              ip6stat.ip6s_reassembled );
865                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Delivered",
866                              ip6stat.ip6s_delivered );
867
868                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
869                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Total",
870                              ip6stat.ip6s_localout );
871                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Raw",
872                              ip6stat.ip6s_rawout );
873                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Fragmented",
874                              ip6stat.ip6s_fragmented );
875                 }
876                 html_table_end( client );
877 #endif
878                 html_table_data_begin( client, "valign=\"top\"" );                        
879                 html_table_begin( client, "" );
880                 {
881
882                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
883                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO",
884                              icmpstat.icps_inhist[ICMP_ECHO] );
885                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO REPLY",
886                              icmpstat.icps_inhist[ICMP_ECHOREPLY] );
887                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "UNREACH",
888                              icmpstat.icps_inhist[ICMP_UNREACH] );
889                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "REDIRECT",
890                              icmpstat.icps_inhist[ICMP_REDIRECT] );
891                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Other",
892                              icmpstat.icps_inhist[ICMP_SOURCEQUENCH]+
893                              icmpstat.icps_inhist[ICMP_ROUTERADVERT]+
894                              icmpstat.icps_inhist[ICMP_ROUTERSOLICIT]+
895                              icmpstat.icps_inhist[ICMP_TIMXCEED]+
896                              icmpstat.icps_inhist[ICMP_PARAMPROB]+
897                              icmpstat.icps_inhist[ICMP_TSTAMP]+
898                              icmpstat.icps_inhist[ICMP_TSTAMPREPLY]+
899                              icmpstat.icps_inhist[ICMP_IREQ]+
900                              icmpstat.icps_inhist[ICMP_IREQREPLY]+
901                              icmpstat.icps_inhist[ICMP_MASKREQ]+
902                              icmpstat.icps_inhist[ICMP_MASKREPLY]
903                         );
904                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bad",
905                              icmpstat.icps_badcode+
906                              icmpstat.icps_tooshort+
907                              icmpstat.icps_checksum+
908                              icmpstat.icps_badlen+
909                              icmpstat.icps_bmcastecho
910                         );
911
912                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
913                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO",
914                              icmpstat.icps_outhist[ICMP_ECHO] );
915                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ECHO REPLY",
916                              icmpstat.icps_outhist[ICMP_ECHOREPLY] );
917                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "UNREACH",
918                              icmpstat.icps_outhist[ICMP_UNREACH] );
919                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "REDIRECT",
920                              icmpstat.icps_outhist[ICMP_REDIRECT] );
921                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Other",
922                              icmpstat.icps_inhist[ICMP_SOURCEQUENCH]+                             
923                              icmpstat.icps_outhist[ICMP_ROUTERADVERT]+
924                              icmpstat.icps_outhist[ICMP_ROUTERSOLICIT]+
925                              icmpstat.icps_outhist[ICMP_TIMXCEED]+
926                              icmpstat.icps_outhist[ICMP_PARAMPROB]+
927                              icmpstat.icps_outhist[ICMP_TSTAMP]+
928                              icmpstat.icps_outhist[ICMP_TSTAMPREPLY]+
929                              icmpstat.icps_outhist[ICMP_IREQ]+
930                              icmpstat.icps_outhist[ICMP_IREQREPLY]+
931                              icmpstat.icps_outhist[ICMP_MASKREQ]+
932                              icmpstat.icps_outhist[ICMP_MASKREPLY]
933                         );
934                 }
935                 html_table_end( client );
936
937 #ifdef CYGPKG_NET_INET6
938                 html_table_data_begin( client, "valign=\"top\"" );                        
939                 html_table_begin( client, "" );
940                 {
941
942                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
943                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO",
944                              icmp6stat.icp6s_inhist[ICMP_ECHO] );
945                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO REPLY",
946                              icmp6stat.icp6s_inhist[ICMP_ECHOREPLY] );
947                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "UNREACH",
948                              icmp6stat.icp6s_inhist[ICMP_UNREACH] );
949                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "REDIRECT",
950                              icmp6stat.icp6s_inhist[ICMP_REDIRECT] );
951                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Other",
952                              icmp6stat.icp6s_inhist[ICMP_SOURCEQUENCH]+
953                              icmp6stat.icp6s_inhist[ICMP_ROUTERADVERT]+
954                              icmp6stat.icp6s_inhist[ICMP_ROUTERSOLICIT]+
955                              icmp6stat.icp6s_inhist[ICMP_TIMXCEED]+
956                              icmp6stat.icp6s_inhist[ICMP_PARAMPROB]+
957                              icmp6stat.icp6s_inhist[ICMP_TSTAMP]+
958                              icmp6stat.icp6s_inhist[ICMP_TSTAMPREPLY]+
959                              icmp6stat.icp6s_inhist[ICMP_IREQ]+
960                              icmp6stat.icp6s_inhist[ICMP_IREQREPLY]+
961                              icmp6stat.icp6s_inhist[ICMP_MASKREQ]+
962                              icmp6stat.icp6s_inhist[ICMP_MASKREPLY]
963                         );
964                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Bad",
965                              icmp6stat.icp6s_badcode+
966                              icmp6stat.icp6s_tooshort+
967                              icmp6stat.icp6s_checksum+
968                              icmp6stat.icp6s_badlen
969                         );
970
971                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
972                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO",
973                              icmp6stat.icp6s_outhist[ICMP_ECHO] );
974                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "ECHO REPLY",
975                              icmp6stat.icp6s_outhist[ICMP_ECHOREPLY] );
976                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "UNREACH",
977                              icmp6stat.icp6s_outhist[ICMP_UNREACH] );
978                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "REDIRECT",
979                              icmp6stat.icp6s_outhist[ICMP_REDIRECT] );
980                     fprintf( client, "<tr><td>%s<td>%lld</tr>\n", "Other",
981                              icmp6stat.icp6s_inhist[ICMP_SOURCEQUENCH]+                             
982                              icmp6stat.icp6s_outhist[ICMP_ROUTERADVERT]+
983                              icmp6stat.icp6s_outhist[ICMP_ROUTERSOLICIT]+
984                              icmp6stat.icp6s_outhist[ICMP_TIMXCEED]+
985                              icmp6stat.icp6s_outhist[ICMP_PARAMPROB]+
986                              icmp6stat.icp6s_outhist[ICMP_TSTAMP]+
987                              icmp6stat.icp6s_outhist[ICMP_TSTAMPREPLY]+
988                              icmp6stat.icp6s_outhist[ICMP_IREQ]+
989                              icmp6stat.icp6s_outhist[ICMP_IREQREPLY]+
990                              icmp6stat.icp6s_outhist[ICMP_MASKREQ]+
991                              icmp6stat.icp6s_outhist[ICMP_MASKREPLY]
992                         );
993                 }
994                 html_table_end( client );
995 #endif
996                 html_table_data_begin( client, "valign=\"top\"" );                        
997                 html_table_begin( client, "" );
998                 {
999
1000                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
1001                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
1002                              udpstat.udps_ipackets );
1003                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bad",
1004                              udpstat.udps_hdrops+
1005                              udpstat.udps_badsum+
1006                              udpstat.udps_badlen+
1007                              udpstat.udps_noport+
1008                              udpstat.udps_noportbcast+
1009                              udpstat.udps_fullsock
1010                         );
1011                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );                    
1012                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Total",
1013                              udpstat.udps_opackets );
1014                 }
1015                 html_table_end( client );
1016
1017                 html_table_data_begin( client, "valign=\"top\"" );                        
1018                 html_table_begin( client, "" );
1019                 {
1020
1021                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Connections" );
1022                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Initiated",
1023                              tcpstat.tcps_connattempt );
1024                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Accepted",
1025                              tcpstat.tcps_accepts );
1026                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Established",
1027                              tcpstat.tcps_connects );
1028                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Closed",
1029                              tcpstat.tcps_closed );
1030
1031                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Received" );
1032                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Packets",
1033                              tcpstat.tcps_rcvtotal );
1034                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Data Packets",
1035                              tcpstat.tcps_rcvpack );
1036                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bytes",
1037                              tcpstat.tcps_rcvbyte );
1038                     
1039                     fprintf( client, "<tr><td><b>%s:</b><td></tr>\n", "Sent" );
1040                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Packets",
1041                              tcpstat.tcps_sndtotal );
1042                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Data Packets",
1043                              tcpstat.tcps_sndpack );
1044                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Bytes",
1045                              tcpstat.tcps_sndbyte );
1046
1047                     
1048                 }
1049                 html_table_end( client );
1050                 
1051                 
1052             }
1053             html_table_row_end( client );
1054
1055         }
1056         html_table_end( client );
1057
1058         html_para_begin( client, "" );
1059         html_heading(client, 3, "Mbufs" );
1060
1061         html_table_begin( client, "border" );
1062         {
1063             html_table_header( client, "Summary", "" );
1064             html_table_header( client, "Types", "" );
1065
1066             html_table_row_begin( client, "" );
1067             {
1068                 html_table_data_begin( client, "valign=\"top\"" );                        
1069                 html_table_begin( client, "" );
1070                 {
1071                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Mbufs",
1072                              mbstat.m_mbufs );
1073                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Clusters",
1074                              mbstat.m_clusters );
1075                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Free Clusters",
1076                              mbstat.m_clfree );
1077                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Drops",
1078                              mbstat.m_drops );
1079                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Waits",
1080                              mbstat.m_wait );
1081                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Drains",
1082                              mbstat.m_drain );
1083 #if defined(CYGPKG_NET_FREEBSD_STACK)
1084                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Copy Fails",
1085                              mbstat.m_mcfail );
1086                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "Pullup Fails",
1087                              mbstat.m_mpfail );
1088 #endif                    
1089
1090                 }
1091                 html_table_end( client );
1092
1093                 html_table_data_begin( client, "valign=\"top\"" );                        
1094                 html_table_begin( client, "" );
1095                 {
1096                     u_long *mtypes;
1097 #if defined(CYGPKG_NET_FREEBSD_STACK)
1098                     mtypes = mbtypes;
1099 #else
1100                     mtypes = mbstat.m_mtypes;
1101 #endif
1102                     
1103                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "FREE",
1104                              mtypes[MT_FREE] );
1105                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "DATA",
1106                              mtypes[MT_DATA] );
1107                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "HEADER",
1108                              mtypes[MT_HEADER] );
1109 #if !defined(CYGPKG_NET_FREEBSD_STACK)                    
1110                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "SOCKET",
1111                              mtypes[MT_SOCKET] );
1112                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "PCB",
1113                              mtypes[MT_PCB] );
1114                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "RTABLE",
1115                              mtypes[MT_RTABLE] );
1116                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "HTABLE",
1117                              mtypes[MT_HTABLE] );
1118                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "ATABLE",
1119                              mtypes[MT_ATABLE] );
1120 #endif
1121                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "SONAME",
1122                              mtypes[MT_SONAME] );
1123 #if !defined(CYGPKG_NET_FREEBSD_STACK)                                        
1124                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "SOOPTS",
1125                              mtypes[MT_SOOPTS] );
1126 #endif
1127                     fprintf( client, "<tr><td>%s<td>%ld</tr>\n", "FTABLE",
1128                              mtypes[MT_FTABLE] );
1129
1130                     /* Ignore the rest for now... */
1131                     
1132                 }
1133                 html_table_end( client );
1134                 
1135             }
1136             html_table_row_end( client );
1137             
1138         }
1139         html_table_end( client );
1140         
1141         
1142         draw_navbar(client);
1143     }
1144     html_body_end(client);
1145
1146     html_end(client);
1147     
1148     freeifaddrs(iflist);
1149     return 1;
1150     
1151 }
1152
1153 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_network_entry,
1154                        "/monitor/network.htm*",
1155                        cyg_monitor_network,
1156                        NULL );
1157
1158         
1159 /* ================================================================= */
1160 /* Instrumentation Monitor
1161  *
1162  * If the CYGPKG_KERNEL_INSTRUMENT option is set, we generate a table
1163  * showing the current instrumentation buffer. If the FLAGS option is
1164  * enabled we also print a table giving control of the flags.
1165  * 
1166  */
1167
1168 #ifdef CYGPKG_KERNEL_INSTRUMENT
1169
1170 /* Instrumentation record. */
1171 struct Instrument_Record
1172 {
1173     CYG_WORD16  type;                   // record type
1174     CYG_WORD16  thread;                 // current thread id
1175     CYG_WORD    timestamp;              // 32 bit timestamp
1176     CYG_WORD    arg1;                   // first arg
1177     CYG_WORD    arg2;                   // second arg
1178 };
1179 typedef struct Instrument_Record Instrument_Record;
1180
1181 /* Instrumentation variables, these live in the
1182  * instrumentation files in the kernel
1183  */
1184 __externC Instrument_Record       *instrument_buffer_pointer;
1185 __externC Instrument_Record       instrument_buffer[];
1186 __externC cyg_uint32              instrument_buffer_size;
1187
1188 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1189     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1190
1191 static cyg_uint32 instrument_flags[(CYG_INSTRUMENT_CLASS_MAX>>8)+1];
1192
1193 #endif
1194
1195 static char cyg_monitor_instrument_blurb1[] =
1196 "<p>Use the checkboxes to enable the events to be recorded. Click "
1197 "the <em>Submit</em> button to start recording. Click the <em>Clear</em> "
1198 "button to clear all instrumentation and to stop recording."
1199 ;
1200
1201 static cyg_bool cyg_monitor_instrument( FILE * client, char *filename,
1202                                         char *formdata, void *arg )
1203 {
1204
1205 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1206     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1207
1208     /* Disable all instrumentation while we generate the page.
1209      * Otherwise we could swamp the information we are really after.
1210      */
1211     
1212     cyg_scheduler_lock();
1213     {
1214         struct instrument_desc_s *id = instrument_desc;
1215         CYG_WORD cl = 0, ev = 0;
1216
1217         for( ; id->msg != 0; id++ )
1218         {
1219             if( id->num > 0xff )
1220             {
1221                 cl = id->num>>8;
1222                 instrument_flags[cl] = 0;
1223             }
1224             else
1225             {
1226                 ev = id->num;
1227                 cyg_instrument_disable( cl<<8, ev );
1228             }
1229         }
1230     }
1231     cyg_scheduler_unlock();
1232
1233 #endif
1234     
1235     /* If we have some form data, deal with it.
1236      */
1237     if( formdata != NULL )
1238     {
1239         char *list[40];
1240         
1241         cyg_formdata_parse( formdata, list, sizeof(list)/sizeof(*list) );
1242
1243 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1244     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1245         
1246         if( cyg_formlist_find( list, "clear" ) != NULL )
1247         {
1248             /* If the clear button is set, then disable all instrumentation flags.
1249              */
1250             int i;
1251             for( i = 0; i < sizeof(instrument_flags)/sizeof(*instrument_flags); i++ )
1252                 instrument_flags[i] = 0;
1253         }
1254         else
1255         {
1256             /* Otherwise all the set checkboxes have been reported to
1257              * us in the form of class=event inputs.
1258              */
1259             char **p;
1260             for( p = list; *p != NULL; p++ )
1261             {
1262                 int cl,ev;
1263                 if( sscanf( *p, "%02x=%02x", &cl, &ev ) == 2 )
1264                     instrument_flags[cl] |= 1<<ev;
1265             }
1266         }
1267 #endif
1268         
1269         /* If the cleartable button has been pressed, clear all the
1270          * table entries. 
1271          */
1272         if( cyg_formlist_find( list, "cleartable" ) != NULL )
1273         {
1274             cyg_scheduler_lock();
1275             {
1276                 Instrument_Record *ibp = instrument_buffer_pointer;
1277                 do
1278                 {
1279                     ibp->type = 0;
1280                     ibp++;
1281                     if( ibp == &instrument_buffer[instrument_buffer_size] )
1282                         ibp = instrument_buffer;
1283                     
1284                 } while( ibp != instrument_buffer_pointer );
1285                 
1286             }
1287             cyg_scheduler_unlock();
1288         }
1289     }
1290     
1291     /* Now start generating the HTML page.
1292      */
1293     html_begin(client);
1294
1295     html_head(client,"eCos Instrumentation Buffer", "");
1296
1297     html_body_begin(client,"");
1298     {
1299         html_heading(client, 2, "Instrumentation Buffer" );
1300
1301         html_form_begin( client, "/monitor/instrument.html", "" );
1302         
1303 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1304     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1305         
1306         /* If we have the flags enabled, generate a table showing all
1307          * the flag names with a checkbox against each.
1308          */
1309
1310         fputs( cyg_monitor_instrument_blurb1, client );
1311         
1312         html_para_begin( client, "" );        
1313         /* Add submit,clear and reset buttons */
1314         html_form_input(client, "submit", "submit", "Submit", "");                
1315         html_form_input(client, "submit", "clear", "Clear", "");                
1316         html_form_input(client, "reset", "reset", "Reset", "");
1317         
1318         html_table_begin( client, "border width=100%" );
1319         {
1320             struct instrument_desc_s *id = instrument_desc;
1321             CYG_WORD cl = 0, ev = 0;
1322             int clc = 0;
1323             char class[5], event[5];
1324
1325             html_table_row_begin( client, "" );
1326
1327             for( ; id->msg != 0; id++ )
1328             {
1329                 if( id->num > 0xff )
1330                 {
1331                     cl = id->num;
1332                     sprintf( class, "%02x", cl>>8 );
1333                     clc = 0;
1334                     
1335                     if( id != instrument_desc )
1336                     {
1337                         html_table_end( client );
1338                         html_table_row_end( client );
1339                         html_table_row_begin( client, "" );
1340                     }
1341                         
1342                     html_table_data_begin( client, "valign=\"top\" width=100%" );
1343                     html_table_begin( client, "width=100%" );
1344                 }
1345                 else
1346                 {
1347                     ev = id->num;
1348                     sprintf( event, "%02x", ev );
1349
1350                     if( (clc%4) == 0 )
1351                     {
1352                         if( clc != 0 )
1353                             html_table_row_end( client );
1354
1355                         html_table_row_begin( client, "" );
1356                     }
1357                     clc++;
1358                     html_table_data_begin( client, "width=25%" );
1359                     html_form_input_checkbox( client, class, event,
1360                                               instrument_flags[cl>>8] & (1<<ev) );
1361                     fputs( id->msg, client );
1362                 }
1363             }            
1364             html_table_end( client );
1365             html_table_row_end( client );
1366         }
1367         html_table_end( client );
1368
1369         /* Add submit,clear and reset buttons */
1370         html_form_input(client, "submit", "submit", "Submit", "");                
1371         html_form_input(client, "submit", "clear", "Clear", "");                
1372         html_form_input(client, "reset", "reset", "Reset", "");
1373
1374 #endif
1375
1376         html_para_begin( client, "" );
1377
1378         html_form_input(client, "submit", "cleartable", "Clear Table", "");
1379
1380         
1381         /*
1382          */
1383         
1384         html_table_begin( client, "border" );
1385         {
1386             Instrument_Record *ibp = instrument_buffer_pointer;
1387
1388             html_table_header( client, "TIME", "" );
1389             html_table_header( client, "THREAD", "" );
1390             html_table_header( client, "EVENT", "" );
1391             html_table_header( client, "ARG1", "" );
1392             html_table_header( client, "ARG2", "" );
1393
1394             do
1395             {
1396                 if( ibp->type != 0 )
1397                 {
1398                     html_table_row_begin(client, "" );
1399                     {
1400                         cyg_handle_t thread = cyg_thread_find(ibp->thread);
1401                         cyg_thread_info info;
1402                     
1403                         html_table_data_begin( client, "" );
1404                         fprintf( client, "%08x",ibp->timestamp);
1405                         html_table_data_begin( client, "" );
1406                         if( thread != 0 &&
1407                             cyg_thread_get_info( thread, ibp->thread, &info ) &&
1408                             info.name != NULL )
1409                             fputs( info.name, client );
1410                         else fprintf( client, "[%04x]", ibp->thread);
1411                         html_table_data_begin( client, "" );
1412 #if defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1413                         fprintf( client, "%s", cyg_instrument_msg(ibp->type));
1414 #else
1415                         fprintf( client, "%04x", ibp->type );
1416 #endif
1417                         html_table_data_begin( client, "" );
1418                         fprintf( client, "%08x", ibp->arg1);
1419                         html_table_data_begin( client, "" );
1420                         fprintf( client, "%08x", ibp->arg2);
1421                     }
1422                     html_table_row_end( client );
1423                 }
1424                 ibp++;
1425                 if( ibp == &instrument_buffer[instrument_buffer_size] )
1426                     ibp = instrument_buffer;
1427                 
1428             } while( ibp != instrument_buffer_pointer );
1429         }
1430         html_table_end( client );
1431
1432         html_para_begin( client, "" );
1433
1434         html_form_input(client, "submit", "cleartable", "Clear Table", "");
1435         
1436         html_form_end( client );
1437         
1438         draw_navbar(client);
1439     }
1440     html_body_end(client);
1441
1442     html_end(client);
1443
1444
1445 #if defined(CYGDBG_KERNEL_INSTRUMENT_FLAGS) && \
1446     defined(CYGDBG_KERNEL_INSTRUMENT_MSGS)
1447
1448     /*
1449      */
1450
1451     cyg_scheduler_lock();
1452     {
1453         struct instrument_desc_s *id = instrument_desc;
1454         CYG_WORD cl = 0, ev = 0;
1455
1456         for( ; id->msg != 0; id++ )
1457         {
1458             if( id->num > 0xff )
1459                 cl = id->num>>8;
1460             else
1461             {
1462                 ev = id->num;
1463                 if( (instrument_flags[cl] & (1<<ev)) != 0 )
1464                     cyg_instrument_enable( cl<<8, ev );
1465             }
1466         }
1467     }
1468     cyg_scheduler_unlock();
1469 #endif
1470     
1471     return true;
1472 }
1473
1474 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_instrument_entry,
1475                        "/monitor/instrument.htm*",
1476                        cyg_monitor_instrument,
1477                        NULL );
1478
1479 #endif
1480
1481 /* ================================================================= */
1482 /* eCos Logo
1483  *
1484  * Define the logo as a byte array, and then define the data structure
1485  * and table entry to allow it to be fetched by the client.
1486  */
1487
1488 static cyg_uint8 ecos_logo_gif[] = {
1489     0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x6f, 0x00, 0x23, 0x00, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00,
1490     0xff, 0xff, 0xff, 0xea, 0x19, 0x00, 0xcc, 0x00, 0x00, 0xfd, 0xfd, 0xfd, 0x83, 0x00, 0x00, 0xf6,
1491     0xf6, 0xf6, 0x2f, 0x2f, 0x2f, 0xef, 0xef, 0xef, 0x19, 0x00, 0x19, 0x45, 0x45, 0x45, 0xbb, 0xbb,
1492     0xbb, 0xe2, 0x3e, 0x3e, 0xe8, 0xbb, 0xd3, 0x3e, 0x3e, 0x3e, 0xfb, 0xfb, 0xfb, 0xbe, 0xbe, 0xbe,
1493     0xf1, 0xed, 0xed, 0xe5, 0x7b, 0x8e, 0xe5, 0x6b, 0x7b, 0xcc, 0xcc, 0xcc, 0x98, 0x95, 0x98, 0xc6,
1494     0xc3, 0xc6, 0x19, 0x19, 0x19, 0xf1, 0xf1, 0xf1, 0x98, 0x98, 0x98, 0xd6, 0xd3, 0xd6, 0x83, 0x83,
1495     0x83, 0xde, 0xde, 0xde, 0xe5, 0x25, 0x25, 0x73, 0x6f, 0x73, 0xea, 0xea, 0xea, 0xe5, 0x8e, 0xa2,
1496     0xe8, 0xe8, 0xe8, 0x7f, 0x7b, 0x7f, 0xe2, 0x56, 0x66, 0x8b, 0x8b, 0x8b, 0x19, 0x19, 0x00, 0xf8,
1497     0xf8, 0xf8, 0x73, 0x73, 0x73, 0xd3, 0xd1, 0xd1, 0x9c, 0x9c, 0x9c, 0x50, 0x50, 0x50, 0xef, 0xce,
1498     0xea, 0x92, 0x8e, 0x92, 0x6f, 0x6f, 0x6f, 0xe2, 0x2f, 0x2f, 0x61, 0x61, 0x61, 0xe5, 0xe5, 0xe5,
1499     0xe8, 0x9f, 0xb8, 0x37, 0x2f, 0x37, 0x66, 0x66, 0x66, 0xe2, 0x4b, 0x50, 0x56, 0x50, 0x56, 0xa9,
1500     0xa5, 0xa9, 0xce, 0xce, 0xce, 0x56, 0x50, 0x50, 0xd9, 0xd9, 0xd9, 0x77, 0x73, 0x77, 0x25, 0x25,
1501     0x2f, 0x6b, 0x6b, 0x6b, 0x9f, 0x9f, 0x9f, 0x87, 0x83, 0x87, 0x3e, 0x37, 0x37, 0xf4, 0xf4, 0xf4,
1502     0x25, 0x25, 0x25, 0xc1, 0xc1, 0xc1, 0x83, 0x7f, 0x83, 0xe5, 0xe2, 0xe2, 0x4b, 0x45, 0x4b, 0xd1,
1503     0xce, 0xd1, 0xaf, 0xac, 0xaf, 0xcc, 0xc9, 0xcc, 0x5b, 0x56, 0x5b, 0xdb, 0xd9, 0xdb, 0x66, 0x61,
1504     0x66, 0xe2, 0xe2, 0xe2, 0xb8, 0xb5, 0xb8, 0x2f, 0x25, 0x2f, 0xc3, 0xc1, 0xc3, 0xe0, 0xde, 0xe0,
1505     0xd3, 0xd3, 0xd3, 0xde, 0xdb, 0xde, 0xac, 0xac, 0xac, 0xce, 0xcc, 0xce, 0x77, 0x6f, 0x73, 0x4b,
1506     0x45, 0x45, 0xc9, 0xc6, 0xc9, 0x45, 0x3e, 0x45, 0x61, 0x5b, 0x61, 0xb5, 0xb2, 0xb5, 0x3e, 0x00,
1507     0x00, 0x8b, 0x87, 0x87, 0x95, 0x92, 0x95, 0xa2, 0x9f, 0xa2, 0xb8, 0xb8, 0xb8, 0x7b, 0x77, 0x7b,
1508     0x9c, 0x98, 0x9c, 0x50, 0x4b, 0x50, 0x6f, 0x6b, 0x6f, 0x6b, 0x66, 0x6b, 0xac, 0xa9, 0xac, 0x8e,
1509     0x8b, 0x8e, 0x8e, 0x00, 0x00, 0xdb, 0xdb, 0xdb, 0xed, 0xed, 0xed, 0x50, 0x4b, 0x4b, 0x3e, 0x37,
1510     0x3e, 0x95, 0x95, 0x95, 0xa5, 0xa2, 0xa5, 0x9f, 0x9c, 0x9f, 0xc1, 0xbe, 0xbe, 0x2f, 0x25, 0x25,
1511     0xd3, 0xd1, 0xd3, 0xf4, 0xf1, 0xf4, 0xc6, 0xc6, 0xc6, 0x8e, 0x8e, 0x8e, 0x25, 0x19, 0x19, 0x66,
1512     0x61, 0x61, 0xb2, 0xaf, 0xb2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1513     0x00, 0x00, 0x00, 0x00, 0x00, 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, 0x2c, 0x00, 0x00,
1538     0x00, 0x00, 0x6f, 0x00, 0x23, 0x00, 0x40, 0x08, 0xff, 0x00, 0x03, 0x08, 0x1c, 0x28, 0x10, 0x41,
1539     0x8a, 0x17, 0x0e, 0x1c, 0x00, 0x58, 0xc8, 0xb0, 0xa1, 0xc3, 0x87, 0x10, 0x21, 0x12, 0x14, 0x28,
1540     0xa0, 0xa2, 0xc5, 0x8b, 0x18, 0x33, 0x6a, 0xdc, 0xb8, 0x91, 0x01, 0x83, 0x11, 0x31, 0x26, 0x12,
1541     0x44, 0x10, 0x91, 0xe1, 0x09, 0x91, 0x28, 0x03, 0x4c, 0xb9, 0x50, 0x72, 0xa1, 0x0a, 0x04, 0x29,
1542     0x09, 0x72, 0x6c, 0x10, 0x73, 0xe2, 0x88, 0x8d, 0x2e, 0x0c, 0xd4, 0x0c, 0x70, 0x73, 0x63, 0x80,
1543     0x88, 0x10, 0x76, 0x0a, 0x6d, 0x18, 0x94, 0x60, 0x03, 0x8e, 0x1a, 0x27, 0x4a, 0x40, 0x5a, 0x51,
1544     0xa9, 0xc5, 0x0e, 0x3b, 0x0d, 0x30, 0x40, 0xca, 0x40, 0x45, 0xc9, 0x14, 0x42, 0x45, 0x72, 0x60,
1545     0xf9, 0xf0, 0x64, 0xd6, 0x00, 0x19, 0x3b, 0xe8, 0xfc, 0x3a, 0x70, 0xe9, 0x45, 0x10, 0x59, 0x0d,
1546     0x70, 0x9c, 0x30, 0xf1, 0x44, 0xcb, 0xb7, 0x70, 0x4b, 0x8a, 0x64, 0x4a, 0xb7, 0xae, 0x5d, 0x01,
1547     0x6c, 0x51, 0xbe, 0x88, 0xcb, 0xb7, 0xef, 0xc2, 0xb9, 0x77, 0x03, 0x0b, 0xbe, 0x98, 0x37, 0xc0,
1548     0x81, 0x88, 0x58, 0x09, 0xde, 0xe0, 0xea, 0xf0, 0xc5, 0x44, 0x0e, 0x0f, 0x13, 0x13, 0x34, 0x30,
1549     0x21, 0x23, 0xdb, 0x8c, 0x63, 0x07, 0x4a, 0xcd, 0x88, 0xd6, 0xa9, 0x45, 0x9a, 0x04, 0x69, 0x60,
1550     0xec, 0xc0, 0x94, 0x41, 0x44, 0xaf, 0x03, 0x53, 0xf8, 0xdd, 0xd1, 0x10, 0xf5, 0xc0, 0xa9, 0x76,
1551     0x41, 0x0f, 0x24, 0xcd, 0xb1, 0xf3, 0xc0, 0x9e, 0x1c, 0x25, 0x88, 0xac, 0xac, 0x91, 0x41, 0x00,
1552     0xc8, 0x6f, 0x77, 0x48, 0x9e, 0x78, 0xc3, 0xaa, 0xdf, 0x03, 0x27, 0xa6, 0x40, 0x28, 0x2a, 0x13,
1553     0xe9, 0x08, 0xd9, 0x93, 0x41, 0xd0, 0xe6, 0xd8, 0x41, 0x42, 0x83, 0x15, 0x02, 0x0d, 0x34, 0xe0,
1554     0x8d, 0x34, 0x73, 0x6a, 0xc6, 0x7e, 0xc3, 0x3b, 0xff, 0x04, 0x3c, 0xb8, 0x3c, 0x5d, 0xdb, 0x03,
1555     0xb7, 0xc2, 0x7d, 0x91, 0x02, 0xa6, 0xe2, 0x13, 0xe0, 0xf9, 0x22, 0x3f, 0xe1, 0x9a, 0x22, 0xd3,
1556     0x09, 0xd0, 0x03, 0x18, 0x00, 0x01, 0x9b, 0x2e, 0x48, 0xec, 0x01, 0x34, 0x10, 0xc3, 0x04, 0xd3,
1557     0x69, 0xa4, 0xd3, 0x5e, 0x11, 0x39, 0x46, 0x96, 0x40, 0x53, 0x44, 0xa4, 0x02, 0x59, 0x1a, 0xe5,
1558     0x97, 0x95, 0x68, 0x17, 0xd1, 0x80, 0x92, 0x77, 0xfd, 0x69, 0x34, 0x81, 0x83, 0x6d, 0x25, 0xe4,
1559     0xe1, 0x87, 0x0e, 0x3c, 0x48, 0x90, 0x6a, 0x0c, 0x89, 0x48, 0x10, 0x77, 0x74, 0x85, 0x44, 0x10,
1560     0x6e, 0x11, 0x4e, 0xd4, 0x9f, 0x84, 0x2b, 0x10, 0x68, 0x97, 0x69, 0x10, 0x31, 0x27, 0xd0, 0x72,
1561     0x38, 0xe6, 0xa8, 0x63, 0x8e, 0x44, 0x4d, 0x74, 0xd4, 0x5d, 0x13, 0xa1, 0xe8, 0x13, 0x41, 0x31,
1562     0x60, 0xe4, 0x02, 0x7a, 0x22, 0xa9, 0xd5, 0xd1, 0x61, 0x35, 0x4e, 0x84, 0x80, 0x42, 0x0e, 0x5d,
1563     0x70, 0x83, 0x48, 0xac, 0xf5, 0xe8, 0xa3, 0x46, 0x2e, 0xac, 0x30, 0x9a, 0x48, 0x45, 0x66, 0xc4,
1564     0x80, 0x77, 0x01, 0x74, 0x69, 0x91, 0x75, 0x05, 0x0a, 0x80, 0xa4, 0x59, 0x5e, 0x92, 0x54, 0x92,
1565     0x94, 0x5f, 0x3d, 0xf9, 0x16, 0x09, 0x59, 0x6d, 0x44, 0x03, 0x98, 0x31, 0xfd, 0x48, 0x58, 0x56,
1566     0x20, 0x20, 0x45, 0x90, 0x71, 0xe2, 0xf5, 0x39, 0xde, 0x44, 0xe6, 0x05, 0xea, 0xdf, 0x4e, 0x1c,
1567     0x90, 0xe0, 0x40, 0x95, 0x7e, 0xf2, 0x45, 0x9e, 0xa0, 0xe6, 0x75, 0xc0, 0x80, 0x04, 0x00, 0x0a,
1568     0x85, 0x00, 0x82, 0x89, 0x86, 0xb7, 0x28, 0xa3, 0x82, 0x4e, 0x40, 0x27, 0x41, 0x94, 0x56, 0x2a,
1569     0xde, 0xa5, 0x98, 0x32, 0x5a, 0x58, 0x6a, 0x7d, 0xed, 0x90, 0x10, 0x93, 0x9e, 0x02, 0x00, 0x2a,
1570     0x47, 0x2e, 0x78, 0x14, 0x2a, 0x53, 0xb6, 0x75, 0xff, 0x0a, 0x91, 0x03, 0x53, 0xc6, 0x84, 0x00,
1571     0x09, 0x7c, 0x5d, 0x70, 0x82, 0x7b, 0x29, 0x21, 0x25, 0xc1, 0xa6, 0x03, 0x35, 0x90, 0x61, 0x46,
1572     0x2e, 0x48, 0x18, 0xec, 0xb0, 0x16, 0xb1, 0x45, 0x62, 0x44, 0x70, 0x92, 0xb5, 0x58, 0x49, 0x0a,
1573     0x0a, 0xb5, 0x91, 0xb1, 0x31, 0xa1, 0x79, 0x11, 0xb5, 0x03, 0x69, 0xc9, 0x51, 0x0c, 0x50, 0x3e,
1574     0x74, 0x01, 0xaf, 0x05, 0x9d, 0x80, 0xaa, 0x0a, 0x36, 0x0a, 0x24, 0x2b, 0x00, 0xdf, 0xa2, 0xb4,
1575     0x82, 0x04, 0x13, 0x4c, 0x00, 0x02, 0x80, 0x96, 0xa1, 0xb4, 0x5d, 0xbb, 0x20, 0xd0, 0xa9, 0xe4,
1576     0x98, 0x3e, 0xd2, 0x46, 0x43, 0x03, 0x76, 0x76, 0x24, 0x17, 0x41, 0xea, 0x31, 0x3b, 0x11, 0x9f,
1577     0xe8, 0xa2, 0xe4, 0xc2, 0x46, 0x2c, 0x0a, 0x30, 0xc2, 0x44, 0x06, 0x1c, 0xac, 0x21, 0xc3, 0xd7,
1578     0x4e, 0x24, 0xe6, 0x8c, 0x02, 0x2f, 0xe8, 0x64, 0x43, 0xcd, 0x36, 0x67, 0xd7, 0x44, 0xda, 0x72,
1579     0x64, 0x21, 0x41, 0x68, 0xea, 0x96, 0xd2, 0x76, 0x74, 0xd1, 0xf8, 0x50, 0xb9, 0x16, 0xff, 0xc4,
1580     0x50, 0xb9, 0xfd, 0x32, 0xe5, 0x42, 0x90, 0x74, 0x5d, 0x69, 0xd1, 0xc2, 0x3b, 0x21, 0x6b, 0x91,
1581     0xc9, 0x0e, 0x65, 0x2c, 0x10, 0xaa, 0xe2, 0x4d, 0xc1, 0x71, 0x60, 0x32, 0xb3, 0xea, 0x59, 0x46,
1582     0x20, 0x6d, 0x6a, 0xb3, 0x00, 0x38, 0x37, 0xb4, 0x83, 0x48, 0xdd, 0x46, 0x09, 0x62, 0x42, 0x4a,
1583     0x8b, 0xd4, 0x31, 0xb1, 0x18, 0x89, 0x1c, 0x2c, 0x47, 0xbe, 0x01, 0x7a, 0xde, 0xd0, 0x18, 0x31,
1584     0xd0, 0x74, 0x43, 0x0e, 0xa0, 0x34, 0x85, 0x0a, 0x87, 0x39, 0x40, 0x02, 0xb8, 0x02, 0xe1, 0xea,
1585     0x50, 0xd8, 0x49, 0x4a, 0x00, 0x1b, 0x0d, 0x9d, 0x71, 0x96, 0xe4, 0x04, 0x53, 0x75, 0x00, 0x37,
1586     0x4a, 0x05, 0x42, 0xa5, 0x9f, 0xdb, 0x15, 0x8d, 0x61, 0x2a, 0xd0, 0xd1, 0x0c, 0x2c, 0x0b, 0x51,
1587     0xad, 0x6d, 0xf2, 0xec, 0xd0, 0x70, 0x35, 0x61, 0x69, 0x71, 0xcb, 0x7a, 0x0b, 0x65, 0x2d, 0x46,
1588     0x21, 0x11, 0x0c, 0x91, 0xce, 0x29, 0x41, 0x80, 0x68, 0x4b, 0x0e, 0xa0, 0xac, 0x35, 0x96, 0xd8,
1589     0x96, 0xd5, 0x51, 0xe7, 0x8f, 0x63, 0x44, 0x73, 0x00, 0x6e, 0xc5, 0xa5, 0x02, 0x09, 0xa8, 0x93,
1590     0xf0, 0xc2, 0xe5, 0x7e, 0xae, 0x1a, 0xd6, 0x08, 0x12, 0xc4, 0x2e, 0x01, 0x85, 0xaf, 0x66, 0x64,
1591     0x75, 0x41, 0x5f, 0xa7, 0xaa, 0xe8, 0xe6, 0xb5, 0x0b, 0x3a, 0x3a, 0x4a, 0x37, 0xe4, 0xae, 0xfb,
1592     0xbf, 0x1a, 0xf7, 0x3e, 0x18, 0x0d, 0x91, 0x0e, 0x14, 0x10, 0x00, 0x3b
1593 };
1594
1595 CYG_HTTPD_DATA( cyg_monitor_ecos_logo_data,
1596                 "image/gif",
1597                 sizeof(ecos_logo_gif), ecos_logo_gif );
1598
1599 CYG_HTTPD_TABLE_ENTRY( cyg_monitor_ecos_logo,
1600                        "/monitor/ecos.gif",
1601                        cyg_httpd_send_data,
1602                        &cyg_monitor_ecos_logo_data );
1603
1604 /*------------------------------------------------------------------ */
1605 /* end of monitor.c                                                  */