# HG changeset patch # User asl # Date 1052735063 0 # Node ID 4ca8a5f30c03277179076651f05caeabd8bf951a # Parent 16d247bb9c70c50d072e9b12e872e8608259076a * src/monitor.c (cyg_monitor_network): Added IPv6 information to the display of network information. * tests/httpd1.c: New file: Simple program to actually run the server so we can test it. * cdl/httpd.cdl: Added the test program. * src/httpd.c: Added support for serving content over IPv6, * doc/httpd.sgml: Added comment about IPv6. diff --git a/packages/net/httpd/current/ChangeLog b/packages/net/httpd/current/ChangeLog --- a/packages/net/httpd/current/ChangeLog +++ b/packages/net/httpd/current/ChangeLog @@ -1,3 +1,16 @@ +2003-05-11 Andrew Lunn + + * src/monitor.c (cyg_monitor_network): Added IPv6 information to + the display of network information. + * tests/httpd1.c: New file: Simple program to actually run the + server so we can test it. + * cdl/httpd.cdl: Added the test program. + +2003-05-10 Andrew Lunn + + * src/httpd.c: Added support for serving content over IPv6, + * doc/httpd.sgml: Added comment about IPv6. + 2003-04-23 Bob Koninckx * cdl/httpd.cdl: Only build monitor in CDL option. diff --git a/packages/net/httpd/current/cdl/httpd.cdl b/packages/net/httpd/current/cdl/httpd.cdl --- a/packages/net/httpd/current/cdl/httpd.cdl +++ b/packages/net/httpd/current/cdl/httpd.cdl @@ -40,7 +40,7 @@ # # Author(s): nickg # Original data: nickg -# Contributors: +# Contributors: andrew Lunn # Date: 2002-10-15 # #####DESCRIPTIONEND#### @@ -150,6 +150,17 @@ cdl_package CYGPKG_HTTPD { compile -library=libextras.a monitor.c } + cdl_component CYGPKG_HTTPD_TESTS { + display "HTTPD tests" + flavor data + no_define + calculated { + "tests/httpd1" + } + description " + This option causes the building of a simple test server." + } + cdl_component CYGPKG_HTTPD_OPTIONS { display "HTTP server build options" flavor none diff --git a/packages/net/httpd/current/doc/httpd.sgml b/packages/net/httpd/current/doc/httpd.sgml --- a/packages/net/httpd/current/doc/httpd.sgml +++ b/packages/net/httpd/current/doc/httpd.sgml @@ -44,6 +44,9 @@ delivering arbitrary web content. For th GoAhead web server is available from www.goahead.com. +This server is also capable of serving content using IPv6 when +the eCos configuration contains IPv6. + @@ -518,7 +521,8 @@ thread edit page where the thread's stat manipulated. The interrupt monitor just shows a table of the current interrupts and indicates which are active. The memory monitor shows a 256 byte page of memory, with controls to change the base address and -display element size. The network monitor page shows +display element size. Note: Accessing invalid memory locations can cause +memory exceptions and the program to crash. The network monitor page shows information extracted from the active network interfaces and protocols. Finally, if kernel instrumentation is enabled, the instrumentation page provides some controls over the instrumentation diff --git a/packages/net/httpd/current/src/httpd.c b/packages/net/httpd/current/src/httpd.c --- a/packages/net/httpd/current/src/httpd.c +++ b/packages/net/httpd/current/src/httpd.c @@ -10,6 +10,7 @@ * This file is part of eCos, the Embedded Configurable Operating * System. * Copyright (C) 2002 Nick Garnett. + * Copyright (C) 2003 Andrew Lunn. * * eCos is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by @@ -43,7 +44,7 @@ * #####DESCRIPTIONBEGIN#### * * Author(s): nickg@calivar.com - * Contributors: nickg@calivar.com + * Contributors: nickg@calivar.com, Andrew.lunn@ascom.ch * Date: 2002-10-14 * Purpose: * Description: @@ -87,6 +88,10 @@ static struct sockaddr_in server_address; static int server_socket = -1; +#ifdef CYGPKG_NET_INET6 +static int server_socket6 = -1; +static struct sockaddr_in6 server_address6; +#endif /* ================================================================= */ /* Thread stacks, etc. @@ -143,12 +148,117 @@ static cyg_bool match( char *name, char return false; } + +/* ================================================================= */ +/* Main processing function */ +/* */ +/* Reads the HTTP header, look it up in the table and calls the */ +/* handler. */ +static void cyg_httpd_process( int client_socket, struct sockaddr *client_address ) { + + int calen = sizeof(*client_address); + int nlc = 0; + char request[CYGNUM_HTTPD_SERVER_BUFFER_SIZE]; + FILE *client; + cyg_httpd_table_entry *entry = cyg_httpd_table; + char *filename; + char *formdata = NULL; + char *p; + cyg_bool success = false; + char name[64]; + char port[10]; + + getnameinfo(client_address, calen, name, sizeof(name), + port, sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); + HTTPD_DIAG("Connection from %s[%s]\n",name,port); + + /* Convert the file descriptor to a C library FILE object so + * we can use fprintf() and friends on it. + */ + client = fdopen( client_socket, "r+"); + + /* We are really only interested in the first line. + */ + fgets( request, sizeof(request), client ); + + HTTPD_DIAG("Request >%s<\n", request ); + + /* Absorb the rest of the header. We nibble it away a + * character at a time like this to avoid having to define + * another buffer to read lines into. If we ever need to take + * more interest in the header fields, we will need to be a + * lot more sophisticated than this. + */ + do{ + int c = getc( client ); + HTTPD_DIAG("%c",c); + if( c == '\n' ) + nlc++; + else if( c != '\r' ) + nlc = 0; + } while(nlc < 2); + + /* Extract the filename and any form data being returned. + * We know that the "GET " request takes 4 bytes. + * TODO: handle POST type requests as well as GET's. + */ + + filename = p = request+4; + + /* Now scan the filename until we hit a space or a '?'. If we + * end on a '?' then the rest is a form request. Put NULs at + * the end of each string. + */ + while( *p != ' ' && *p != '?' ) + p++; + if( *p == '?' ) + formdata = p+1; + *p = 0; + + if( formdata != NULL ) + { + while( *p != ' ' ) + p++; + *p = 0; + } + + HTTPD_DIAG("Request filename >%s< formdata >%s<\n",filename,formdata?formdata:"-NULL-"); + + HTTPD_DIAG("table: %08x...%08x\n",cyg_httpd_table, cyg_httpd_table_end); + + /* Now scan the table for a matching entry. If we find one + * call the handler routine. If that returns true then we + * terminate the scan, otherwise we keep looking. + */ + while( entry != cyg_httpd_table_end ) + { + HTTPD_DIAG("try %08x: %s\n", entry, entry->pattern); + + if( match( filename, entry->pattern ) ) + { + if( (success = entry->handler( client, filename, formdata, entry->arg )) ) + break; + } + + entry++; + } + + /* If we failed to find a match in the table, send a "not + * found" response. + * TODO: add an optional fallback to go look for files in + * some filesystem, somewhere. + */ + if( !success ) + cyg_httpd_send_html( client, NULL, NULL, cyg_httpd_not_found ); + + fclose(client); +} + /* ================================================================= */ /* Main HTTP server * - * This just loops, collects client connections, reads the HTTP - * header, look it up in the table and calls the handler. - */ + * This just loops, collects client connections, and calls the main + * process function on the connects*/ static void cyg_httpd_server( cyg_addrword_t arg ) { @@ -156,108 +266,36 @@ static void cyg_httpd_server( cyg_addrwo { int err; int client_socket; - struct sockaddr_in client_address; - int calen; - int nlc = 0; - char request[CYGNUM_HTTPD_SERVER_BUFFER_SIZE]; - FILE *client; - cyg_httpd_table_entry *entry = cyg_httpd_table; - char *filename; - char *formdata = NULL; - char *p; - cyg_bool success = false; + struct sockaddr client_address; + int calen = sizeof(client_address); + fd_set readfds; + int n; /* Wait for a connection. */ - client_socket = accept( server_socket, (struct sockaddr *)&client_address, &calen ); - - HTTPD_DIAG("Connection from %08x[%d]\n",client_address.sin_addr.s_addr, - client_address.sin_port); - - /* Convert the file descriptor to a C library FILE object so - * we can use fprintf() and friends on it. - */ - client = fdopen( client_socket, "r+"); - - /* We are really only interested in the first line. - */ - fgets( request, sizeof(request), client ); - - HTTPD_DIAG("Request >%s<\n", request ); - - /* Absorb the rest of the header. We nibble it away a - * character at a time like this to avoid having to define - * another buffer to read lines into. If we ever need to take - * more interest in the header fields, we will need to be a - * lot more sophisticated than this. - */ - do{ - int c = getc( client ); - HTTPD_DIAG("%c",c); - if( c == '\n' ) - nlc++; - else if( c != '\r' ) - nlc = 0; - } while(nlc < 2); - - /* Extract the filename and any form data being returned. - * We know that the "GET " request takes 4 bytes. - * TODO: handle POST type requests as well as GET's. - */ - - filename = p = request+4; - - /* Now scan the filename until we hit a space or a '?'. If we - * end on a '?' then the rest is a form request. Put NULs at - * the end of each string. - */ - while( *p != ' ' && *p != '?' ) - p++; - if( *p == '?' ) - formdata = p+1; - *p = 0; - - if( formdata != NULL ) - { - while( *p != ' ' ) - p++; - *p = 0; + FD_ZERO(&readfds); + FD_SET(server_socket, &readfds); +#ifdef CYGPKG_NET_INET6 + FD_SET(server_socket6, &readfds); + n = (server_socket > server_socket6 ? server_socket : server_socket6) + 1; +#else + n = server_socket + 1; +#endif + select(n,&readfds,NULL,NULL,NULL); + if (FD_ISSET(server_socket, &readfds)) { + client_socket = accept( server_socket, &client_address, &calen ); + cyg_httpd_process(client_socket, &client_address); + err = close( client_socket ); + CYG_ASSERT( err == 0, "fclose() returned error"); } - - HTTPD_DIAG("Request filename >%s< formdata >%s<\n",filename,formdata?formdata:"-NULL-"); - - HTTPD_DIAG("table: %08x...%08x\n",cyg_httpd_table, cyg_httpd_table_end); - - /* Now scan the table for a matching entry. If we find one - * call the handler routine. If that returns true then we - * terminate the scan, otherwise we keep looking. - */ - while( entry != cyg_httpd_table_end ) - { - HTTPD_DIAG("try %08x: %s\n", entry, entry->pattern); - - if( match( filename, entry->pattern ) ) - { - if( (success = entry->handler( client, filename, formdata, entry->arg )) ) - break; - } - - entry++; +#ifdef CYGPKG_NET_INET6 + if (FD_ISSET(server_socket6, &readfds)) { + client_socket = accept( server_socket6, &client_address, &calen ); + cyg_httpd_process(client_socket, &client_address); + err = close( client_socket ); + CYG_ASSERT( err == 0, "fclose(AF_INET6) returned error"); } - - /* If we failed to find a match in the table, send a "not - * found" response. - * TODO: add an optional fallback to go look for files in - * some filesystem, somewhere. - */ - if( !success ) - cyg_httpd_send_html( client, NULL, NULL, cyg_httpd_not_found ); - - /* All done, close the connection - */ - err = fclose( client ); - CYG_ASSERT( err == 0, "fclose() returned error"); - +#endif } while(1); } @@ -288,7 +326,12 @@ static void cyg_httpd_init(cyg_addrword_ server_address.sin_len = sizeof(server_address); server_address.sin_addr.s_addr = INADDR_ANY; server_address.sin_port = htons(CYGNUM_HTTPD_SERVER_PORT); - +#ifdef CYGPKG_NET_INET6 + server_address6.sin6_family = AF_INET6; + server_address6.sin6_len = sizeof(server_address6); + server_address6.sin6_addr = in6addr_any; + server_address6.sin6_port = htons(CYGNUM_HTTPD_SERVER_PORT); +#endif /* Get the network going. This is benign if the application has * already done this. */ @@ -305,7 +348,17 @@ static void cyg_httpd_init(cyg_addrword_ err = listen( server_socket, SOMAXCONN ); CYG_ASSERT( err == 0, "listen() returned error" ); +#ifdef CYGPKG_NET_INET6 + server_socket6 = socket( AF_INET6, SOCK_STREAM, IPPROTO_TCP ); + CYG_ASSERT( server_socket6 > 0, "Socket AF_INET6 create failed"); + err = bind( server_socket6, (struct sockaddr *)&server_address6, + sizeof(server_address6) ); + CYG_ASSERT( err == 0, "bind(AF_INET6) returned error"); + + err = listen( server_socket6, SOMAXCONN ); + CYG_ASSERT( err == 0, "listen(AF_INET6) returned error" ); +#endif /* If we are configured to have more than one server thread, * create them now. */ @@ -428,7 +481,7 @@ static void cyg_httpd_init(cyg_addrword_ list[i] = p; - while( *p != 0 && i < size-1 ) + while( p && *p != 0 && i < size-1 ) { if( *p == '&' ) { diff --git a/packages/net/httpd/current/src/monitor.c b/packages/net/httpd/current/src/monitor.c --- a/packages/net/httpd/current/src/monitor.c +++ b/packages/net/httpd/current/src/monitor.c @@ -10,6 +10,7 @@ * This file is part of eCos, the Embedded Configurable Operating * System. * Copyright (C) 2002 Nick Garnett. + * Copyright (C) 2003 Andrew Lunn * * eCos is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by @@ -43,7 +44,7 @@ * #####DESCRIPTIONBEGIN#### * * Author(s): nickg@calivar.com - * Contributors: nickg@calivar.com + * Contributors: nickg@calivar.com, andrew.lunn@ascom.ch * Date: 2002-10-14 * Purpose: * Description: @@ -87,10 +88,11 @@ #include #include #include - +#include #define _KERNEL #include +#include #include #include #include @@ -106,6 +108,14 @@ #include #include #include +#ifdef CYGPKG_NET_INET6 +#include +#include +#include +#include +#include +#endif + #include @@ -677,24 +687,9 @@ CYG_HTTPD_TABLE_ENTRY( cyg_monitor_memor static cyg_bool cyg_monitor_network( FILE * client, char *filename, char *formdata, void *arg ) { - struct ifconf ifconf; - char conf[256]; - int err; - int sock; + struct ifaddrs *iflist, *ifp; - /* Start by opening a socket and getting a list of all the - * interfaces present. - */ - { - memset( conf, 0, sizeof(conf) ); - - sock = socket( AF_INET, SOCK_DGRAM, 0 ); - - ifconf.ifc_len = sizeof(conf); - ifconf.ifc_buf = (caddr_t)conf; - - err = ioctl( sock, SIOCGIFCONF, &ifconf ); - } + getifaddrs(&iflist); html_begin(client); @@ -708,116 +703,71 @@ static cyg_bool cyg_monitor_network( FIL html_table_begin( client, "border" ); { + char addr[64]; int i; - struct ifreq *ifrp; - struct sockaddr *sa; - + ifp = iflist; + html_table_header( client, "Interface", "" ); html_table_header( client, "Status", "" ); - ifrp = ifconf.ifc_req; - - while( ifconf.ifc_len && ifrp->ifr_name[0] ) + while( ifp != (struct ifaddrs *)NULL) { - struct ifreq ifreq = *ifrp; - - /* For some reason we get two entries for each - * interface in the list: one with an AF_INET address - * and one with an AF_LINK address. We are currently - * only interested in the AF_INET ones. - */ - - if( ifrp->ifr_addr.sa_family == AF_INET ) + if (ifp->ifa_addr->sa_family != AF_LINK) { - - html_table_row_begin(client, "" ); - { + + html_table_row_begin(client, "" ); + { html_table_data_begin( client, "" ); - fprintf( client, "%s", ifrp->ifr_name); + fprintf( client, "%s", ifp->ifa_name); html_table_data_begin( client, "" ); html_table_begin( client, "" ); { - struct ether_drv_stats ethstats; - /* Get the interface's flags and display * the interesting ones. */ - if( ioctl( sock, SIOCGIFFLAGS, &ifreq ) >= 0 ) + html_table_row_begin(client, "" ); + fprintf( client, "Flags\n" ); + for( i = 0; i < 16; i++ ) + { + switch( ifp->ifa_flags & (1<ifa_addr, sizeof(*ifp->ifa_addr), + addr, sizeof(addr), NULL, 0, NI_NUMERICHOST); + fprintf( client, "Address%s\n", addr); + html_table_row_end( client ); + + if (ifp->ifa_netmask) { - html_table_row_begin(client, "" ); - fprintf( client, "Flags\n" ); - for( i = 0; i < 16; i++ ) - { - switch( ifreq.ifr_flags & (1<= 0 ) - { - struct sockaddr_in *inaddr = - (struct sockaddr_in *)&ifreq.ifr_addr; - - html_table_row_begin(client, "" ); - fprintf( client, "Address%s\n", - inet_ntoa(inaddr->sin_addr)); - html_table_row_end( client ); + html_table_row_begin(client, "" ); + getnameinfo(ifp->ifa_netmask, sizeof(*ifp->ifa_netmask), + addr, sizeof(addr), NULL, 0, NI_NUMERICHOST); + fprintf( client, "Mask%s\n", addr); + html_table_row_end( client ); } - /* If there's a netmask, show that. */ - if( ioctl( sock, SIOCGIFNETMASK, &ifreq ) >= 0 ) - { - struct sockaddr_in *inaddr = - (struct sockaddr_in *)&ifreq.ifr_addr; - - html_table_row_begin(client, "" ); - fprintf( client, "Mask%s\n", - inet_ntoa(inaddr->sin_addr)); - html_table_row_end( client ); - } - - /* If there's a broadcast address, show that. */ - if( ioctl( sock, SIOCGIFBRDADDR, &ifreq ) >= 0 ) + if (ifp->ifa_broadaddr) { - struct sockaddr_in *inaddr = - (struct sockaddr_in *)&ifreq.ifr_broadaddr; - - html_table_row_begin(client, "" ); - fprintf( client, "Broadcast Address%s\n", - inet_ntoa(inaddr->sin_addr)); - html_table_row_end( client ); - } - - /* If the ethernet driver collects - * statistics, fetch those and show some - * of them. - */ - - ethstats.ifreq = ifreq; - if( ioctl( sock, SIOCGIFSTATS, ðstats ) >= 0 ) - { - fprintf( client, "Hardware%s\n", - ethstats.description ); - fprintf( client, "Packets Received%d\n", - ethstats.rx_count ); - fprintf( client, "Packets Sent%d\n", - ethstats.tx_count ); - fprintf( client, "Interrupts%d\n", - ethstats.interrupts ); + html_table_row_begin(client, "" ); + getnameinfo(ifp->ifa_broadaddr, sizeof(*ifp->ifa_broadaddr), + addr, sizeof(addr), NULL, 0, NI_NUMERICHOST); + fprintf( client, "Broadcast%s\n", addr); + html_table_row_end( client ); } } html_table_end( client ); @@ -825,22 +775,7 @@ static cyg_bool cyg_monitor_network( FIL html_table_row_end( client ); } - - /* Scan the addresses, even if we are not interested - * in this interface, since we must skip to the next. - */ - do - { - sa = &ifrp->ifr_addr; - if (sa->sa_len <= sizeof(*sa)) { - ifrp++; - } else { - ifrp=(struct ifreq *)(sa->sa_len + (char *)sa); - ifconf.ifc_len -= sa->sa_len - sizeof(*sa); - } - ifconf.ifc_len -= sizeof(*ifrp); - - } while (!ifrp->ifr_name[0] && ifconf.ifc_len); + ifp = ifp->ifa_next; } } html_table_end( client ); @@ -857,8 +792,14 @@ static cyg_bool cyg_monitor_network( FIL html_para_begin( client, "" ); html_table_begin( client, "border"); { - html_table_header( client, "IP", "" ); - html_table_header( client, "ICMP", "" ); + html_table_header( client, "IPv4", "" ); +#ifdef CYGPKG_NET_INET6 + html_table_header( client, "IPv6", "" ); +#endif + html_table_header( client, "ICMPv4", "" ); +#ifdef CYGPKG_NET_INET6 + html_table_header( client, "ICMPv6", "" ); +#endif html_table_header( client, "UDP", "" ); html_table_header( client, "TCP", "" ); @@ -892,10 +833,35 @@ static cyg_bool cyg_monitor_network( FIL ipstat.ips_rawout ); fprintf( client, "%s%ld\n", "Fragmented", ipstat.ips_fragmented ); - } html_table_end( client ); +#ifdef CYGPKG_NET_INET6 + html_table_data_begin( client, "valign=\"top\"" ); + html_table_begin( client, "" ); + { + fprintf( client, "%s:\n", "Received" ); + fprintf( client, "%s%lld\n", "Total", + ip6stat.ip6s_total ); + fprintf( client, "%s%lld\n", "Bad", + ip6stat.ip6s_tooshort+ + ip6stat.ip6s_toosmall + ); + fprintf( client, "%s%lld\n", "Reassembled", + ip6stat.ip6s_reassembled ); + fprintf( client, "%s%lld\n", "Delivered", + ip6stat.ip6s_delivered ); + + fprintf( client, "%s:\n", "Sent" ); + fprintf( client, "%s%lld\n", "Total", + ip6stat.ip6s_localout ); + fprintf( client, "%s%lld\n", "Raw", + ip6stat.ip6s_rawout ); + fprintf( client, "%s%lld\n", "Fragmented", + ip6stat.ip6s_fragmented ); + } + html_table_end( client ); +#endif html_table_data_begin( client, "valign=\"top\"" ); html_table_begin( client, "" ); { @@ -955,6 +921,65 @@ static cyg_bool cyg_monitor_network( FIL } html_table_end( client ); +#ifdef CYGPKG_NET_INET6 + html_table_data_begin( client, "valign=\"top\"" ); + html_table_begin( client, "" ); + { + + fprintf( client, "%s:\n", "Received" ); + fprintf( client, "%s%lld\n", "ECHO", + icmp6stat.icp6s_inhist[ICMP_ECHO] ); + fprintf( client, "%s%lld\n", "ECHO REPLY", + icmp6stat.icp6s_inhist[ICMP_ECHOREPLY] ); + fprintf( client, "%s%lld\n", "UNREACH", + icmp6stat.icp6s_inhist[ICMP_UNREACH] ); + fprintf( client, "%s%lld\n", "REDIRECT", + icmp6stat.icp6s_inhist[ICMP_REDIRECT] ); + fprintf( client, "%s%lld\n", "Other", + icmp6stat.icp6s_inhist[ICMP_SOURCEQUENCH]+ + icmp6stat.icp6s_inhist[ICMP_ROUTERADVERT]+ + icmp6stat.icp6s_inhist[ICMP_ROUTERSOLICIT]+ + icmp6stat.icp6s_inhist[ICMP_TIMXCEED]+ + icmp6stat.icp6s_inhist[ICMP_PARAMPROB]+ + icmp6stat.icp6s_inhist[ICMP_TSTAMP]+ + icmp6stat.icp6s_inhist[ICMP_TSTAMPREPLY]+ + icmp6stat.icp6s_inhist[ICMP_IREQ]+ + icmp6stat.icp6s_inhist[ICMP_IREQREPLY]+ + icmp6stat.icp6s_inhist[ICMP_MASKREQ]+ + icmp6stat.icp6s_inhist[ICMP_MASKREPLY] + ); + fprintf( client, "%s%lld\n", "Bad", + icmp6stat.icp6s_badcode+ + icmp6stat.icp6s_tooshort+ + icmp6stat.icp6s_checksum+ + icmp6stat.icp6s_badlen + ); + + fprintf( client, "%s:\n", "Sent" ); + fprintf( client, "%s%lld\n", "ECHO", + icmp6stat.icp6s_outhist[ICMP_ECHO] ); + fprintf( client, "%s%lld\n", "ECHO REPLY", + icmp6stat.icp6s_outhist[ICMP_ECHOREPLY] ); + fprintf( client, "%s%lld\n", "UNREACH", + icmp6stat.icp6s_outhist[ICMP_UNREACH] ); + fprintf( client, "%s%lld\n", "REDIRECT", + icmp6stat.icp6s_outhist[ICMP_REDIRECT] ); + fprintf( client, "%s%lld\n", "Other", + icmp6stat.icp6s_inhist[ICMP_SOURCEQUENCH]+ + icmp6stat.icp6s_outhist[ICMP_ROUTERADVERT]+ + icmp6stat.icp6s_outhist[ICMP_ROUTERSOLICIT]+ + icmp6stat.icp6s_outhist[ICMP_TIMXCEED]+ + icmp6stat.icp6s_outhist[ICMP_PARAMPROB]+ + icmp6stat.icp6s_outhist[ICMP_TSTAMP]+ + icmp6stat.icp6s_outhist[ICMP_TSTAMPREPLY]+ + icmp6stat.icp6s_outhist[ICMP_IREQ]+ + icmp6stat.icp6s_outhist[ICMP_IREQREPLY]+ + icmp6stat.icp6s_outhist[ICMP_MASKREQ]+ + icmp6stat.icp6s_outhist[ICMP_MASKREPLY] + ); + } + html_table_end( client ); +#endif html_table_data_begin( client, "valign=\"top\"" ); html_table_begin( client, "" ); { @@ -1106,9 +1131,8 @@ static cyg_bool cyg_monitor_network( FIL html_body_end(client); html_end(client); - - close( sock ); + freeifaddrs(iflist); return 1; } diff --git a/packages/net/httpd/current/tests/httpd1.c b/packages/net/httpd/current/tests/httpd1.c new file mode 100644 --- /dev/null +++ b/packages/net/httpd/current/tests/httpd1.c @@ -0,0 +1,89 @@ +//========================================================================== +// +// ./net/http/current/tests/httpd1.c +// +// +//========================================================================== +//####ECOSGPLCOPYRIGHTBEGIN#### +// ------------------------------------------- +// This file is part of eCos, the Embedded Configurable Operating System. +// Copyright (C) 2003 Andrew Lunn +// +// eCos is free software; you can redistribute it and/or modify it under +// the terms of the GNU General Public License as published by the Free +// Software Foundation; either version 2 or (at your option) any later version. +// +// eCos is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +// for more details. +// +// You should have received a copy of the GNU General Public License along +// with eCos; if not, write to the Free Software Foundation, Inc., +// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. +// +// As a special exception, if other files instantiate templates or use macros +// or inline functions from this file, or you compile this file and link it +// with other works to produce a work based on this file, this file does not +// by itself cause the resulting work to be covered by the GNU General Public +// License. However the source code for this file must still be made available +// in accordance with section (3) of the GNU General Public License. +// +// This exception does not invalidate any other reasons why a work based on +// this file might be covered by the GNU General Public License. +// +// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. +// at http://sources.redhat.com/ecos/ecos-license/ +// ------------------------------------------- +//####ECOSGPLCOPYRIGHTEND#### +//========================================================================== +//#####DESCRIPTIONBEGIN#### +// +// Author(s): andrew.lunn@ascom.ch +// Contributors: andrew.lunn@ascom.ch +// Date: 2003-04-29 +// Purpose: +// Description: +// +// +//####DESCRIPTIONEND#### +// +//========================================================================== + +#include +#include + +#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000) +static char stack[STACK_SIZE]; +static cyg_thread thread_data; +static cyg_handle_t thread_handle; + +void +httpd_test(cyg_addrword_t p) +{ + + CYG_TEST_INIT(); + + init_all_network_interfaces(); + + cyg_thread_delay(1 * 60 * 100); + + CYG_TEST_PASS_FINISH( "httpd test finished" ); +} + +void +cyg_start(void) +{ + // Create a main thread, so we can run the scheduler and have time 'pass' + cyg_thread_create(10, // Priority - just a number + httpd_test, // entry + 0, // entry parameter + "httpd test", // Name + &stack[0], // Stack + STACK_SIZE, // Size + &thread_handle, // Handle + &thread_data // Thread data structure + ); + cyg_thread_resume(thread_handle); // Start it + cyg_scheduler_start(); +}