public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] Loopback patch
@ 2000-06-16  4:37 Sorin Babeanu
  2000-06-21  4:15 ` Hugo Tyson
  0 siblings, 1 reply; 5+ messages in thread
From: Sorin Babeanu @ 2000-06-16  4:37 UTC (permalink / raw)
  To: ecos-discuss; +Cc: 'Ratanasavetavadhana, Michael M'

[-- Attachment #1: Type: text/plain, Size: 190 bytes --]

The attached patch contains a few modifications I have made in order to make
the loopback interface work on eCos without a real network device.
It also contains tests for ping, udp and tcp.

[-- Attachment #2: loopback_patch --]
[-- Type: text/x-diff, Size: 39510 bytes --]

diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/cdl/net.cdl net-1.0b1/net/tcpip/v1_0b1/cdl/net.cdl
--- net-1.0b1-orig/net/tcpip/v1_0b1/cdl/net.cdl	Mon May 29 12:32:37 2000
+++ net-1.0b1/net/tcpip/v1_0b1/cdl/net.cdl	Mon May 29 12:55:33 2000
@@ -259,7 +259,7 @@
             display "Build networking tests (demo programs)"
             flavor  bool
             no_define
-            default_value 0
+            default_value 1
             description   "
                 This option enables the building of the network tests
                 which at this time are just demos."
@@ -276,7 +276,13 @@
                               tests/nc_test_master \
                               tests/nc_test_slave \
                               tests/tcp_echo \
-                              tests/ping_test" : "" }
+			      tests/tcp_source \
+			      tests/tcp_sink \
+                              tests/ping_test \
+			      tests/ping_lo_test \
+			      tests/tcp_lo_test \
+			      tests/udp_lo_test \
+			      tests/tcp_lo_select" : "" }
                 description   "
                     This option specifies the set of tests for the networking package."
             }
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/include/network.h net-1.0b1/net/tcpip/v1_0b1/include/network.h
--- net-1.0b1-orig/net/tcpip/v1_0b1/include/network.h	Mon May 29 12:32:41 2000
+++ net-1.0b1/net/tcpip/v1_0b1/include/network.h	Mon May 29 12:42:24 2000
@@ -42,7 +42,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas
+// Contributors: gthomas,sorin
 // Date:         2000-01-10
 // Purpose:      
 // Description:  
@@ -86,6 +86,7 @@
 #endif
 
 extern void init_all_network_interfaces(void);
+extern cyg_bool_t init_loopback_interface(void); /* Added by sorin@netappi.com */
 
 extern void  route_reinit(void);
 extern void  perror(const char *);
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/src/lib/network_support.c net-1.0b1/net/tcpip/v1_0b1/src/lib/network_support.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/src/lib/network_support.c	Mon May 29 12:32:42 2000
+++ net-1.0b1/net/tcpip/v1_0b1/src/lib/network_support.c	Mon May 29 12:43:15 2000
@@ -42,7 +42,7 @@
 //#####DESCRIPTIONBEGIN####
 //
 // Author(s):    gthomas
-// Contributors: gthomas
+// Contributors: gthomas, sorin@netappi.com
 // Date:         2000-01-10
 // Purpose:      
 // Description:  
@@ -89,7 +89,7 @@
 #define string(s) _string(s)
 
 #if defined(CYGHWR_NET_DRIVER_ETH0_ADDRS_IP) \
- || defined(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP)
+ || defined(CYGHWR_NET_DRIVER_ETH1_ADDRS_IP) || 1
 //
 // Internal function which builds up a fake BOOTP database for
 // an interface.
@@ -218,4 +218,80 @@
     }
 #endif
 #endif
+}
+
+//  
+//   Initialize loopback interface  ----------   Added by sorin@netappi.com 
+//
+
+cyg_bool_t init_loopback_interface(void)
+{
+struct sockaddr_in *addrp;
+struct ifreq ifr;
+int s;
+int one = 1;
+struct ecos_rtentry route;
+struct in_addr netmask, gateway;
+
+diag_printf("Init_loopback_interface\n");
+    s = socket(AF_INET, SOCK_DGRAM, 0); 
+    if (s < 0) {
+        perror("socket");
+        return false;
+    }
+    if (setsockopt(s, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one))) {
+        perror("setsockopt");
+        return false;
+    }
+
+    addrp = (struct sockaddr_in *) &ifr.ifr_addr;
+    memset(addrp, 0, sizeof(*addrp));
+    addrp->sin_family = AF_INET;
+    addrp->sin_len = sizeof(*addrp);
+    addrp->sin_port = 0;
+    addrp->sin_addr.s_addr = htonl(INADDR_LOOPBACK) ; 
+
+    strcpy(ifr.ifr_name, "los0");
+    if (ioctl(s, SIOCSIFADDR, &ifr)) {
+        perror("SIOCIFADDR");
+        return false;
+    }
+    
+    netmask.s_addr = 0xffffff00;
+    if (ioctl(s, SIOCSIFNETMASK, &ifr)) {
+        perror("SIOCSIFNETMASK");
+        return false;
+    }
+    ifr.ifr_flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
+    if (ioctl(s, SIOCSIFFLAGS, &ifr)) {
+        perror("SIOCSIFFLAGS");
+        return false;
+    }
+
+    gateway.s_addr = htonl(INADDR_LOOPBACK);  
+    memset(&route, 0, sizeof(route));
+        addrp->sin_family = AF_INET;
+        addrp->sin_port = 0;
+        addrp->sin_addr.s_addr = 0x7f000001 & *(unsigned int *)&netmask;
+        memcpy(&route.rt_dst, addrp, sizeof(*addrp));
+        addrp->sin_addr = netmask;
+        memcpy(&route.rt_genmask, addrp, sizeof(*addrp));
+        addrp->sin_addr = gateway;
+        memcpy(&route.rt_gateway, addrp, sizeof(*addrp));
+
+        route.rt_dev = ifr.ifr_name;
+        route.rt_flags = RTF_UP|RTF_GATEWAY;
+        route.rt_metric = 0;
+
+        if (ioctl(s, SIOCADDRT, &route)) {
+diag_printf("Route - dst: %s", inet_ntoa(((struct sockaddr_in *)&route.rt_dst)->sin_addr));
+diag_printf(", mask: %s", inet_ntoa(((struct sockaddr_in *)&route.rt_genmask)->sin_addr));
+diag_printf(", gateway: %s\n", inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
+         if (errno != EEXIST) {
+             perror("SIOCADDRT 3");
+             return false;
+         }
+        }
+    close(s);
+    return true;
 }
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/src/sys/net/if_loop.c net-1.0b1/net/tcpip/v1_0b1/src/sys/net/if_loop.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/src/sys/net/if_loop.c	Mon May 29 12:32:43 2000
+++ net-1.0b1/net/tcpip/v1_0b1/src/sys/net/if_loop.c	Mon May 29 12:42:18 2000
@@ -199,6 +199,20 @@
 #include <net/bpf.h>
 #endif
 
+#include <netdev.h>
+
+int loioctl (register struct ifnet *, u_long, caddr_t);
+void lortrequest (int, struct rtentry *, struct sockaddr *);
+
+void loopattach (int);
+bool loop_init (struct cyg_netdevtab_entry *);
+
+int looutput (struct ifnet *ifp, struct mbuf *m, struct sockaddr *dst, struct rtentry *rt);
+
+int if_simloop( struct ifnet *, register struct mbuf *, struct sockaddr *, register struct rtentry *);
+
+
+
 #if defined(LARGE_LOMTU)
 #define LOMTU	(131072 +  MHLEN + MLEN)
 #else
@@ -211,16 +225,25 @@
   
 struct	ifnet loif[NLOOP];
 
+NETDEVTAB_ENTRY(loop_netdev,"los0",loop_init,&loif);
+
+bool
+loop_init(tab)
+	struct cyg_netdevtab_entry *tab;
+{
+loopattach(1);
+return true;
+}
+
 void
 loopattach(n)
 	int n;
 {
 	register int i;
 	register struct ifnet *ifp;
-
 	for (i = NLOOP; i--; ) {
 		ifp = &loif[i];
-		sprintf(ifp->if_xname, "lo%d", i);
+		sprintf(ifp->if_xname, "los%d", i);
 		ifp->if_softc = NULL;
 		ifp->if_mtu = LOMTU;
 		ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
@@ -243,6 +266,41 @@
 	struct sockaddr *dst;
 	register struct rtentry *rt;
 {
+        if ((m->m_flags & M_PKTHDR) == 0)
+                panic("looutput no HDR");
+
+        if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+                m_freem(m);
+                return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+                        rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+        }
+        ifp->if_opackets++;
+        ifp->if_obytes += m->m_pkthdr.len;
+#if 1   /* XXX */
+        switch (dst->sa_family) {
+        case AF_INET:
+        case AF_IPX:
+        case AF_NS:
+        case AF_ISO:
+        case AF_APPLETALK:
+                break;
+        default:
+                printf("looutput: af=%d unexpected", dst->sa_family);
+                m_freem(m);
+                return (EAFNOSUPPORT);
+        }
+#endif
+        return(if_simloop(ifp, m, dst, 0));
+}
+
+
+int
+if_simloop(ifp, m, dst, rt)
+	struct ifnet *ifp;
+	register struct mbuf *m;
+	struct sockaddr *dst;
+	register struct rtentry *rt;
+{
 	int s, isr;
 	register struct ifqueue *ifq = 0;
 
@@ -406,7 +464,6 @@
 	struct rtentry *rt;
 	struct sockaddr *sa;
 {
-
 	if (rt)
 		rt->rt_rmx.rmx_mtu = LOMTU;
 }
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/src/sys/netinet/if_ether.c net-1.0b1/net/tcpip/v1_0b1/src/sys/netinet/if_ether.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/src/sys/netinet/if_ether.c	Mon May 29 12:32:43 2000
+++ net-1.0b1/net/tcpip/v1_0b1/src/sys/netinet/if_ether.c	Mon May 29 12:42:18 2000
@@ -148,7 +148,7 @@
 static	struct llinfo_arp *arplookup __P((u_int32_t, int, int));
 static	void in_arpinput __P((struct mbuf *));
 
-extern	struct ifnet loif;
+extern	struct ifnet loif[];
 LIST_HEAD(, llinfo_arp) llinfo_arp;
 struct	ifqueue arpintrq = {0, 0, 0, 50};
 int	arp_inuse, arp_allocated, arp_intimer;
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/src/sys/netinet/ip_input.c net-1.0b1/net/tcpip/v1_0b1/src/sys/netinet/ip_input.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/src/sys/netinet/ip_input.c	Mon May 29 12:32:43 2000
+++ net-1.0b1/net/tcpip/v1_0b1/src/sys/netinet/ip_input.c	Mon May 29 12:42:18 2000
@@ -260,7 +260,6 @@
 	register int i;
 	const u_int16_t defbaddynamicports_tcp[] = DEFBADDYNAMICPORTS_TCP;
 	const u_int16_t defbaddynamicports_udp[] = DEFBADDYNAMICPORTS_UDP;
-
 	pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
 	if (pr == 0)
 		panic("ip_init");
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/tests/ping_lo_test.c net-1.0b1/net/tcpip/v1_0b1/tests/ping_lo_test.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/tests/ping_lo_test.c	Thu Jan  1 02:00:00 1970
+++ net-1.0b1/net/tcpip/v1_0b1/tests/ping_lo_test.c	Mon May 29 12:42:19 2000
@@ -0,0 +1,257 @@
+//==========================================================================
+//
+//      tests/ping_test.c
+//
+//      Simple test of PING (ICMP) and networking support
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+//                                                                          
+// -------------------------------------------                              
+// The contents of this file are subject to the Red Hat eCos Public License 
+// Version 1.1 (the "License"); you may not use this file except in         
+// compliance with the License.  You may obtain a copy of the License at    
+// http://www.redhat.com/                                                   
+//                                                                          
+// Software distributed under the License is distributed on an "AS IS"      
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the 
+// License for the specific language governing rights and limitations under 
+// the License.                                                             
+//                                                                          
+// The Original Code is eCos - Embedded Configurable Operating System,      
+// released September 30, 1998.                                             
+//                                                                          
+// The Initial Developer of the Original Code is Red Hat.                   
+// Portions created by Red Hat are                                          
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.                             
+// All Rights Reserved.                                                     
+// -------------------------------------------                              
+//                                                                          
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources,
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    gthomas, sorin@netappi.com
+// Contributors: gthomas, sorin@netappi.com
+// Date:         2000-01-10
+// Purpose:      
+// Description:  
+//              
+//
+//####DESCRIPTIONEND####
+//
+//==========================================================================
+
+// PING test code
+
+#include <network.h>
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char stack[STACK_SIZE];
+static cyg_thread thread_data;
+static cyg_handle_t thread_handle;
+
+#define NUM_PINGS 16
+#define MAX_PACKET 4096
+static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET];
+
+#define UNIQUEID 0x1234
+
+void
+cyg_test_exit(void)
+{
+    diag_printf("... Done\n");
+    while (1) ;
+}
+
+void
+pexit(char *s)
+{
+    perror(s);
+    cyg_test_exit();
+}
+
+// Compute INET checksum
+int
+inet_cksum(u_short *addr, int len)
+{
+    register int nleft = len;
+    register u_short *w = addr;
+    register u_short answer;
+    register u_int sum = 0;
+    u_short odd_byte = 0;
+
+    /*
+     *  Our algorithm is simple, using a 32 bit accumulator (sum),
+     *  we add sequential 16 bit words to it, and at the end, fold
+     *  back all the carry bits from the top 16 bits into the lower
+     *  16 bits.
+     */
+    while( nleft > 1 )  {
+        sum += *w++;
+        nleft -= 2;
+    }
+
+    /* mop up an odd byte, if necessary */
+    if( nleft == 1 ) {
+        *(u_char *)(&odd_byte) = *(u_char *)w;
+        sum += odd_byte;
+    }
+
+    /*
+     * add back carry outs from top 16 bits to low 16 bits
+     */
+    sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */
+    sum += (sum >> 16);                     /* add carry */
+    answer = ~sum;                          /* truncate to 16 bits */
+    return (answer);
+}
+
+static int
+show_icmp(unsigned char *pkt, int len, 
+          struct sockaddr_in *from, struct sockaddr_in *to)
+{
+    cyg_tick_count_t *tp, tv;
+    struct ip *ip;
+    struct icmp *icmp;
+    tv = cyg_current_time();
+    ip = (struct ip *)pkt;
+    if ((len < sizeof(*ip)) || ip->ip_v != IPVERSION) {
+        diag_printf("%s: Short packet or not IP! - Len: %d, Version: %d\n", 
+                    inet_ntoa(from->sin_addr), len, ip->ip_v);
+        return 0;
+    }
+    icmp = (struct icmp *)(pkt + sizeof(*ip));
+    len -= (sizeof(*ip) + 8);
+    tp = (cyg_tick_count_t *)&icmp->icmp_data;
+    if (icmp->icmp_type != ICMP_ECHOREPLY) {
+        diag_printf("%s: Invalid ICMP - type: %d\n", 
+                    inet_ntoa(from->sin_addr), icmp->icmp_type);
+        return 0;
+    }
+    if (icmp->icmp_id != UNIQUEID) {
+        diag_printf("%s: ICMP received for wrong id - sent: %x, recvd: %x\n", 
+                    inet_ntoa(from->sin_addr), UNIQUEID, icmp->icmp_id);
+    }
+    diag_printf("%d bytes from %s: ", len, inet_ntoa(from->sin_addr));
+    diag_printf("icmp_seq=%d", icmp->icmp_seq);
+    diag_printf(", time=%dms\n", (int)(tv - *tp)*10);
+    return (from->sin_addr.s_addr == to->sin_addr.s_addr);
+}
+
+static void
+ping_host(int s, struct sockaddr_in *host)
+{
+    struct icmp *icmp = (struct icmp *)pkt1;
+    int icmp_len = 64;
+    int seq, ok_recv, bogus_recv;
+    cyg_tick_count_t *tp;
+    long *dp;
+    struct sockaddr_in from;
+    int i, len, fromlen;
+
+    ok_recv = 0;
+    bogus_recv = 0;
+    diag_printf("PING server %s\n", inet_ntoa(host->sin_addr));
+    for (seq = 0;  seq < NUM_PINGS;  seq++) {
+        // Build ICMP packet
+        icmp->icmp_type = ICMP_ECHO;
+        icmp->icmp_code = 0;
+        icmp->icmp_cksum = 0;
+        icmp->icmp_seq = seq;
+        icmp->icmp_id = 0x1234;
+        // Set up ping data
+        tp = (cyg_tick_count_t *)&icmp->icmp_data;
+        *tp++ = cyg_current_time();
+        dp = (long *)tp;
+        for (i = sizeof(*tp);  i < icmp_len;  i += sizeof(*dp)) {
+            *dp++ = i;
+        }
+        // Add checksum
+        icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8);
+        // Send it off
+        if (sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host)) < 0) {
+            perror("sendto");
+            continue;
+        }
+        // Wait for a response
+        fromlen = sizeof(from);
+        len = recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&from, &fromlen);
+        if (len < 0) {
+            perror("recvfrom");
+        } else {
+            if (show_icmp(pkt2, len, &from, host)) {
+                ok_recv++;
+            } else {
+                bogus_recv++;
+            }
+        }
+    }
+    diag_printf("Sent %d packets, received %d OK, %d bad\n", NUM_PINGS, ok_recv, bogus_recv);
+}
+
+static void
+ping_test_loopback(void)
+{
+    struct protoent *p;
+    struct timeval tv;
+    struct sockaddr_in host;
+    int s;
+
+    if ((p = getprotobyname("icmp")) == (struct protoent *)0) {
+        perror("getprotobyname");
+        return;
+    }
+    s = socket(AF_INET, SOCK_RAW, p->p_proto);
+    if (s < 0) {
+        perror("socket");
+        return;
+    }
+    tv.tv_sec = 1;
+    tv.tv_usec = 0;
+    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
+    // Set up host address
+    host.sin_family = AF_INET;
+    host.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    host.sin_port = 0;
+    ping_host(s, &host);
+    // Now try a bogus host
+    host.sin_addr.s_addr = htonl(ntohl(host.sin_addr.s_addr) + 32);
+    ping_host(s, &host);
+}
+
+void
+net_test(cyg_addrword_t p)
+{
+    diag_printf("Start PING test\n");
+    init_loopback_interface();
+        ping_test_loopback();
+    cyg_test_exit();
+}
+
+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
+                      net_test,          // entry
+                      0,                 // entry parameter
+                      "Network 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();
+}
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/tests/tcp_lo_select.c net-1.0b1/net/tcpip/v1_0b1/tests/tcp_lo_select.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/tests/tcp_lo_select.c	Thu Jan  1 02:00:00 1970
+++ net-1.0b1/net/tcpip/v1_0b1/tests/tcp_lo_select.c	Mon May 29 12:42:19 2000
@@ -0,0 +1,305 @@
+//==========================================================================
+//
+//      tests/tcp_lo_test.c
+// 
+//      Simple TCP throughput test 
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+// 
+// -------------------------------------------
+// The contents of this file are subject to the Red Hat eCos Public License
+// Version 1.1 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://www.redhat.com/  
+//      
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+// 
+// The Original Code is eCos - Embedded Configurable Operating System,
+// released September 30, 1998.
+// 
+// The Initial Developer of the Original Code is Red Hat.
+// Portions created by Red Hat are
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+// All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    sorin@netappi.com 
+// Contributors: gthomas,sorin@netappi.com 
+// Date:         2000-05-24
+
+
+// Network throughput test code
+
+#include <network.h>
+
+#define SOURCE_PORT1 9990
+#define SOURCE_PORT2   9991
+
+#define NUM_BUF 1024
+#define MAX_BUF 8192
+static unsigned char data_buf1[MAX_BUF];
+static unsigned char data_buf2[MAX_BUF];
+static unsigned char data_buf_write1[MAX_BUF]="Client 1 is alive. You may continue ....";
+static unsigned char data_buf_write2[MAX_BUF]="Client 2 is alive. You may continue ....";
+
+
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char stack_server[STACK_SIZE];
+static cyg_thread server_thread_data;
+static cyg_handle_t server_thread_handle;
+
+static char stack_client1[STACK_SIZE];
+static cyg_thread client1_thread_data; 
+static cyg_handle_t client1_thread_handle;  
+
+static char stack_client2[STACK_SIZE];
+static cyg_thread client2_thread_data;
+static cyg_handle_t client2_thread_handle;
+
+
+#define MAIN_THREAD_PRIORITY     CYGPKG_NET_THREAD_PRIORITY-2
+
+void
+cyg_test_exit(void)
+{
+    diag_printf("... Done\n");
+    while (1) ;     
+}
+
+void
+pexit(char *s)
+{
+    perror(s);
+    cyg_test_exit();
+}
+
+
+void server(void)
+{
+    int s_s1, e_s1, s_s2, e_s2;
+    struct sockaddr_in e_s1_addr,e_s2_addr,local;
+    fd_set in_fds;
+    int len;
+    int num;
+    
+    char *hello_string=" Hello eCos network \n";
+    diag_printf("TCP SERVER:");
+    diag_printf(hello_string);
+
+    s_s1 = socket(AF_INET, SOCK_STREAM, 0);
+    if (s_s1 < 0) {
+        pexit("stream socket");
+    }   
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_len = sizeof(local);
+    local.sin_port = ntohs(SOURCE_PORT1);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    if(bind(s_s1, (struct sockaddr *) &local, sizeof(local)) < 0) {
+        pexit("bind /source_1/ error");
+    }
+    listen(s_s1, SOMAXCONN);
+
+    s_s2 = socket(AF_INET, SOCK_STREAM, 0);    
+    if (s_s2 < 0) {    
+        pexit("stream socket");
+    }  
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_len = sizeof(local);
+    local.sin_port = ntohs(SOURCE_PORT2);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    if(bind(s_s2, (struct sockaddr *) &local, sizeof(local)) < 0) {    
+        pexit("bind /source_2/ error");
+    }
+    listen(s_s2, SOMAXCONN);    
+
+   
+    e_s1 = 0; e_s2 = 0; 
+
+    
+    while (true) {
+	FD_ZERO(&in_fds);
+	FD_SET(s_s1, &in_fds);
+	FD_SET(s_s2, &in_fds);
+        num = select ( max(s_s1,s_s2)+1, &in_fds,0,0,0);
+	if (FD_ISSET(s_s1,&in_fds)) {
+		len = sizeof(e_s1_addr);
+        	if ((e_s1 = accept(s_s1,(struct sockaddr *)&e_s1_addr,&len))<0) 
+			{
+			pexit("accept /source_1/");
+    			}
+	diag_printf("TCP SERVER connection from %s: %d\n",
+	       inet_ntoa(e_s1_addr.sin_addr),ntohs(e_s1_addr.sin_port));
+        }
+        if (FD_ISSET(s_s2,&in_fds)) {
+		len = sizeof(e_s2_addr);
+		if ((e_s2 = accept(s_s2,(struct sockaddr *)&e_s2_addr,&len))<0)
+			{
+			pexit("accept /source_2/");
+			}
+        diag_printf("TCP SERVER connection from %s:%d\n",
+               inet_ntoa(e_s2_addr.sin_addr), ntohs(e_s2_addr.sin_port));
+        }
+
+        if ((e_s1 != 0) && ( e_s2 != 0)) {
+            break;
+            }
+     
+	}   /* while (true) */ 
+
+     if ((len = read(e_s1, data_buf1, MAX_BUF)) < 0  )
+        {
+                perror("I/O error");
+        }
+   diag_printf("SERVER : %s\n",data_buf1);
+
+     if ((len = read(e_s2, data_buf2, MAX_BUF)) < 0  )    
+        {
+                perror("I/O error");
+        }
+   diag_printf("SERVER : %s\n",data_buf2);
+    
+}
+
+void client1(void)
+{
+    int s_source;
+    struct sockaddr_in local;
+    int len;
+
+    diag_printf("client 1 :started\n");
+    
+    s_source = socket(AF_INET, SOCK_STREAM, 0);
+    if (s_source < 0) {
+        pexit("stream socket");
+    }
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_port = htons(SOURCE_PORT1);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    
+    if (connect(s_source, (struct sockaddr *)&local, sizeof(local)) < 0) {
+        pexit("Can't connect to target");
+    }
+    
+    if ((len = write(s_source,data_buf_write1,40)) < 0)
+	{
+	  diag_printf("Error writing buffer\n");
+        } 
+}
+
+void client2(void)
+{
+    int s_source;
+    struct sockaddr_in local;
+    int len;
+    
+    diag_printf("client 2 :started\n");
+    
+    s_source = socket(AF_INET, SOCK_STREAM, 0);
+    if (s_source < 0) {
+        pexit("stream socket");
+    }
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_port = htons(SOURCE_PORT2);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+   
+    if (connect(s_source, (struct sockaddr *)&local, sizeof(local)) < 0) {
+        pexit("Can't connect to target");
+    }
+    
+    if ((len = write(s_source,data_buf_write2,40)) < 0)
+        {
+          diag_printf("Error writing buffer\n");
+        }
+}
+
+
+void
+tcp_server(cyg_addrword_t param)
+{
+    diag_printf("Start TCP server - test\n");
+    server();
+    cyg_test_exit();
+}
+
+void
+tcp_client_1(cyg_addrword_t param)
+{
+    diag_printf("Start TCP client 1 - test\n");
+    client1(); 
+}
+
+void
+tcp_client_2(cyg_addrword_t param)
+{
+    diag_printf("Start TCP client 2 - test\n");
+    client2();
+}
+
+
+void
+cyg_start(void)
+{
+    int i;
+    init_loopback_interface();  
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      tcp_server,             // entry
+                      0,                    // entry parameter
+                      "Network TCP test",       // Name
+                      &stack_server[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &server_thread_handle,       // Handle
+                      &server_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(server_thread_handle);  // Start it
+
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      tcp_client_1,             // entry
+                      0,                    // entry parameter
+                      "Network TCP test",       // Name
+                      &stack_client1[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &client1_thread_handle,       // Handle
+                      &client1_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(client1_thread_handle);  // Start it
+
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      tcp_client_2,             // entry
+                      0,                    // entry parameter
+                      "Network TCP test",       // Name
+                      &stack_client2[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &client2_thread_handle,       // Handle
+                      &client2_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(client2_thread_handle);  // Start it
+
+
+    cyg_scheduler_start();
+}
+
+
+
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/tests/tcp_lo_test.c net-1.0b1/net/tcpip/v1_0b1/tests/tcp_lo_test.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/tests/tcp_lo_test.c	Thu Jan  1 02:00:00 1970
+++ net-1.0b1/net/tcpip/v1_0b1/tests/tcp_lo_test.c	Mon May 29 12:42:19 2000
@@ -0,0 +1,218 @@
+//==========================================================================
+//
+//      tests/tcp_lo_test.c
+// 
+//      Simple TCP throughput test 
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+// 
+// -------------------------------------------
+// The contents of this file are subject to the Red Hat eCos Public License
+// Version 1.1 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://www.redhat.com/  
+//      
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+// 
+// The Original Code is eCos - Embedded Configurable Operating System,
+// released September 30, 1998.
+// 
+// The Initial Developer of the Original Code is Red Hat.
+// Portions created by Red Hat are
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+// All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    sorin@netappi.com 
+// Contributors: gthomas,sorin@netappi.com 
+// Date:         2000-05-24
+
+
+// Network throughput test code
+
+#include <network.h>
+
+#define SOURCE_PORT 9990
+#define SINK_PORT   9991
+
+#define NUM_BUF 1024
+#define MAX_BUF 8192
+static unsigned char data_buf[MAX_BUF];
+static unsigned char data_buf_write[MAX_BUF]="Client is alive. You may continue ....";
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char stack_server[STACK_SIZE];
+static cyg_thread server_thread_data;
+static cyg_handle_t server_thread_handle;
+
+static char stack_client[STACK_SIZE];
+static cyg_thread client_thread_data; 
+static cyg_handle_t client_thread_handle;  
+
+
+#define MAIN_THREAD_PRIORITY     CYGPKG_NET_THREAD_PRIORITY-2
+
+void
+cyg_test_exit(void)
+{
+    diag_printf("... Done\n");
+    while (1) ;     
+}
+
+void
+pexit(char *s)
+{
+    perror(s);
+    cyg_test_exit();
+}
+
+
+void server(void)
+{
+    int s_source, e_source;
+    struct sockaddr_in e_source_addr, local;
+    int one = 1;
+    fd_set in_fds;
+    int len;
+    
+    char *hello_string=" Hello eCos network \n";
+    diag_printf("TCP SERVER:");
+    diag_printf(hello_string);
+
+    s_source = socket(AF_INET, SOCK_STREAM, 0);
+    if (s_source < 0) {
+        pexit("stream socket");
+    }   
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_len = sizeof(local);
+    local.sin_port = ntohs(SOURCE_PORT);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    if(bind(s_source, (struct sockaddr *) &local, sizeof(local)) < 0) {
+        pexit("bind /source/ error");
+    }
+    if (setsockopt(s_source, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
+        pexit("setsockopt /source/ SO_REUSEADDR");
+    }
+    if (setsockopt(s_source, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one))) {
+        pexit("setsockopt /source/ SO_REUSEPORT");
+    }
+    listen(s_source, SOMAXCONN);
+   
+    e_source = 0; 
+    while (true) {
+	FD_ZERO(&in_fds);
+	FD_SET(s_source, &in_fds);
+        if ((e_source = accept(s_source,(struct sockaddr *)&e_source_addr,&len))<0) {
+	pexit("accept /source/");
+    }
+	diag_printf("TCP SERVER connection from %s: %d\n",
+	       inet_ntoa(e_source_addr.sin_addr),ntohs(e_source_addr.sin_port));
+
+        if (e_source != 0) {
+            break;
+        }
+	}   /* while (true) */ 
+
+     if ((len = read(e_source, data_buf, MAX_BUF)) < 0  )
+        {
+                perror("I/O error");
+        }
+   diag_printf("SERVER : %s\n",data_buf);
+    
+}
+
+void client(void)
+{
+    int s_source;
+    struct sockaddr_in local;
+    int one = 1;
+    int len;
+
+    diag_printf("client:started\n");
+    
+    s_source = socket(AF_INET, SOCK_STREAM, 0);
+    if (s_source < 0) {
+        pexit("stream socket");
+    }
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_port = htons(SOURCE_PORT);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    
+    if (connect(s_source, (struct sockaddr *)&local, sizeof(local)) < 0) {
+        pexit("Can't connect to target");
+    }
+    
+    if ((len = write(s_source,data_buf_write,40)) < 0)
+	{
+	  diag_printf("Error writing buffer\n");
+        } 
+}
+
+void
+tcp_server(cyg_addrword_t param)
+{
+    diag_printf("Start TCP server - test\n");
+    server();
+    cyg_test_exit();
+}
+
+void
+tcp_client(cyg_addrword_t param)
+{
+    diag_printf("Start TCP client - test\n");
+    client(); 
+}
+
+
+
+void
+cyg_start(void)
+{
+    int i;
+    init_loopback_interface();  
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      tcp_server,             // entry
+                      0,                    // entry parameter
+                      "Network TCP test",       // Name
+                      &stack_server[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &server_thread_handle,       // Handle
+                      &server_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(server_thread_handle);  // Start it
+
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      tcp_client,             // entry
+                      0,                    // entry parameter
+                      "Network TCP test",       // Name
+                      &stack_client[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &client_thread_handle,       // Handle
+                      &client_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(client_thread_handle);  // Start it
+    cyg_scheduler_start();
+}
+
+
+
diff -urw --new-file net-1.0b1-orig/net/tcpip/v1_0b1/tests/udp_lo_test.c net-1.0b1/net/tcpip/v1_0b1/tests/udp_lo_test.c
--- net-1.0b1-orig/net/tcpip/v1_0b1/tests/udp_lo_test.c	Thu Jan  1 02:00:00 1970
+++ net-1.0b1/net/tcpip/v1_0b1/tests/udp_lo_test.c	Mon May 29 12:42:19 2000
@@ -0,0 +1,191 @@
+//==========================================================================
+//
+//      tests/udp_lo_test.c
+// 
+//      Simple UDP throughput test
+//
+//==========================================================================
+//####COPYRIGHTBEGIN####
+// 
+// -------------------------------------------
+// The contents of this file are subject to the Red Hat eCos Public License
+// Version 1.1 (the "License"); you may not use this file except in
+// compliance with the License.  You may obtain a copy of the License at
+// http://www.redhat.com/  
+//      
+// Software distributed under the License is distributed on an "AS IS"
+// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See the
+// License for the specific language governing rights and limitations under
+// the License.
+// 
+// The Original Code is eCos - Embedded Configurable Operating System,
+// released September 30, 1998.
+// 
+// The Initial Developer of the Original Code is Red Hat.
+// Portions created by Red Hat are
+// Copyright (C) 1998, 1999, 2000 Red Hat, Inc.
+// All Rights Reserved.
+// -------------------------------------------
+//
+//####COPYRIGHTEND####
+//####BSDCOPYRIGHTBEGIN####
+//
+// -------------------------------------------
+//
+// Portions of this software may have been derived from OpenBSD or other sources
+// and are covered by the appropriate copyright disclaimers included herein.
+//
+// -------------------------------------------
+//
+//####BSDCOPYRIGHTEND####
+//==========================================================================
+//#####DESCRIPTIONBEGIN####
+//
+// Author(s):    sorin@netappi.com 
+// Contributors: gthomas,sorin@netappi.com 
+// Date:         2000-05-24
+
+
+// Network throughput test code
+
+#include <network.h>
+
+#define SOURCE_PORT 9990
+#define SINK_PORT   9991
+
+#define NUM_BUF 1024
+#define MAX_BUF 8192
+static unsigned char data_buf[MAX_BUF];
+static unsigned char data_buf_write[MAX_BUF]="Client UDP is alive. You may continue ....";
+
+#define STACK_SIZE CYGNUM_HAL_STACK_SIZE_TYPICAL
+static char stack_server[STACK_SIZE];
+static cyg_thread server_thread_data;
+static cyg_handle_t server_thread_handle;
+
+static char stack_client[STACK_SIZE];
+static cyg_thread client_thread_data; 
+static cyg_handle_t client_thread_handle;  
+
+
+#define MAIN_THREAD_PRIORITY     CYGPKG_NET_THREAD_PRIORITY-2
+
+void
+cyg_test_exit(void)
+{
+    diag_printf("... Done\n");
+    while (1) ;     
+}
+
+void
+pexit(char *s)
+{
+    perror(s);
+    cyg_test_exit();
+}
+
+
+void server(void)
+{
+    int s_source;
+    struct sockaddr_in local,c_addr;
+    int one = 1, c_len;
+    int len;
+    
+    char *hello_string=" Hello eCos network \n";
+    diag_printf("UDP SERVER:");
+    diag_printf(hello_string);
+
+    s_source = socket(AF_INET, SOCK_DGRAM, 0);
+    if (s_source < 0) {
+        pexit("stream socket");
+    }   
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_len = sizeof(local);
+    local.sin_port = ntohs(SOURCE_PORT);
+    local.sin_addr.s_addr = htonl(INADDR_ANY);  //accepts everyone...
+    if(bind(s_source, (struct sockaddr *) &local, sizeof(local)) < 0) {
+        pexit("bind /source/ error");
+    }
+     c_len = sizeof(c_addr);
+
+     if ((len = recvfrom(s_source, data_buf, sizeof(data_buf),0,(struct sockaddr *)&c_addr,&c_len)) < 0  )
+        {
+                perror("I/O error");
+        }
+   diag_printf("SERVER : message arrived from %s\n",inet_ntoa(c_addr.sin_addr));
+   diag_printf("SERVER : Message : %s\n",data_buf);
+   close(s_source); 
+}
+
+void client(void)
+{
+    int s_source;
+    struct sockaddr_in local;
+    int len;
+
+    diag_printf("client:started\n");
+    
+    s_source = socket(AF_INET, SOCK_DGRAM, 0);
+    if (s_source < 0) {
+        pexit("stream socket");
+    }
+    memset(&local, 0, sizeof(local));
+    local.sin_family = AF_INET;
+    local.sin_port = htons(SOURCE_PORT);
+    local.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+    if ( (len= sendto(s_source,data_buf_write,sizeof(data_buf_write),0,(struct sockaddr *)&local,sizeof(local))) < 0 )  
+	{
+	  diag_printf("Error writing buffer\n");
+        }
+    close(s_source); 
+}
+
+void
+udp_server(cyg_addrword_t param)
+{
+    diag_printf("Start UDP server - test\n");
+    server();
+    cyg_test_exit();
+}
+
+void
+udp_client(cyg_addrword_t param)
+{
+    diag_printf("Start UDP client - test\n");
+    client(); 
+}
+
+
+
+void
+cyg_start(void)
+{
+    init_loopback_interface();  
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      udp_server,             // entry
+                      0,                    // entry parameter
+                      "Network UDP test",       // Name
+                      &stack_server[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &server_thread_handle,       // Handle
+                      &server_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(server_thread_handle);  // Start it
+
+    cyg_thread_create(MAIN_THREAD_PRIORITY, // Priority
+                      udp_client,             // entry
+                      0,                    // entry parameter
+                      "Network UDP test",       // Name
+                      &stack_client[0],            // Stack
+                      STACK_SIZE,           // Size
+                      &client_thread_handle,       // Handle
+                      &client_thread_data          // Thread data structure
+            );
+    cyg_thread_resume(client_thread_handle);  // Start it
+    cyg_scheduler_start();
+}
+
+
+

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] Loopback patch
  2000-06-16  4:37 [ECOS] Loopback patch Sorin Babeanu
@ 2000-06-21  4:15 ` Hugo Tyson
  2000-06-21 11:00   ` [ECOS] Loopback patch adopted OK Hugo Tyson
  2001-09-05  0:10   ` [ECOS] Loopback patch Hugo Tyson
  0 siblings, 2 replies; 5+ messages in thread
From: Hugo Tyson @ 2000-06-21  4:15 UTC (permalink / raw)
  To: ecos-discuss


"Sorin Babeanu" <sorin@netappi.com> writes:
> The attached patch contains a few modifications I have made in order to make
> the loopback interface work on eCos without a real network device.
> It also contains tests for ping, udp and tcp.

Just to keep folks up to date: Sorin, thanks for that.  I'm in the process
of adopting it into the trunk - actually a variation on your patch which
sets up the loopback dev in init_all_network_interfaces(), and is more
configurable for 0,1,N loopback devs.

The tests are great, thanks, we can start to run meaningful network tests
on all platforms with those in place, I'll just be adding PASS/FAIL
messages so we can automate those in our test farm.

It'll all show up in anoncvs by the end of this week.

Is there any call for me to supply an alternative patch on this forum?
I won't do so unless people ask.  Any replies to the list please, not me.

	- Huge

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] Loopback patch adopted OK
  2000-06-21  4:15 ` Hugo Tyson
@ 2000-06-21 11:00   ` Hugo Tyson
  2001-09-05  0:10     ` Hugo Tyson
  2001-09-05  0:10   ` [ECOS] Loopback patch Hugo Tyson
  1 sibling, 1 reply; 5+ messages in thread
From: Hugo Tyson @ 2000-06-21 11:00 UTC (permalink / raw)
  To: ecos-discuss


Hugo Tyson <hmt@cygnus.co.uk> writes:
> "Sorin Babeanu" <sorin@netappi.com> writes:
> > The attached patch contains a few modifications I have made in order to make
> > the loopback interface work on eCos without a real network device.
> > It also contains tests for ping, udp and tcp.
> 
> Just to keep folks up to date: Sorin, thanks for that.  I'm in the process
> of adopting it into the trunk - actually a variation on your patch which
> sets up the loopback dev in init_all_network_interfaces(), and is more
> configurable for 0,1,N loopback devs.
> 
> The tests are great, thanks, we can start to run meaningful network tests
> on all platforms with those in place, I'll just be adding PASS/FAIL
> messages so we can automate those in our test farm.
> 
> It'll all show up in anoncvs by the end of this week.
> 
> Is there any call for me to supply an alternative patch on this forum?
> I won't do so unless people ask.  Any replies to the list please, not me.

Phew, done that... ;-)

Sorin, I didn't see what the change in if_loop.c (pasted below) achieved,
so I didn't adopt it.  Can you explain more, convince me?  (I have got the
location it patches right haven't I, ie. looutput()?)

It seems to just do a load of checking twice, in a different order; I mean
the original looutput() checks for RTF_REJECT|RTF_BLACKHOLE &c, and returns
EAFNOSUPPORT with a bad AF.  Was this just experimentation while you were
testing the startup code, that leaked out?

Anyway, thanks again for the contribution; keep up the good work!

Watch anoncvs for our updates to emerge... end of the week sometime.

	- Huge


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 int
 looutput(ifp, m, dst, rt)
        struct ifnet *ifp;
        register struct mbuf *m;
 	struct sockaddr *dst;
 	register struct rtentry *rt;
 {
+        if ((m->m_flags & M_PKTHDR) == 0)
+                panic("looutput no HDR");
+
+        if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+                m_freem(m);
+                return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+                        rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+        }
+        ifp->if_opackets++;
+        ifp->if_obytes += m->m_pkthdr.len;
+#if 1   /* XXX */
+        switch (dst->sa_family) {
+        case AF_INET:
+        case AF_IPX:
+        case AF_NS:
+        case AF_ISO:
+        case AF_APPLETALK:
+                break;
+        default:
+                printf("looutput: af=%d unexpected", dst->sa_family);
+                m_freem(m);
+                return (EAFNOSUPPORT);
+        }
+#endif
+        return(if_simloop(ifp, m, dst, 0));
+}
+
+
+int
+if_simloop(ifp, m, dst, rt)
+	struct ifnet *ifp;
+	register struct mbuf *m;
+	struct sockaddr *dst;
+	register struct rtentry *rt;
+{
 	int s, isr;
 	register struct ifqueue *ifq = 0;
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] Loopback patch
  2000-06-21  4:15 ` Hugo Tyson
  2000-06-21 11:00   ` [ECOS] Loopback patch adopted OK Hugo Tyson
@ 2001-09-05  0:10   ` Hugo Tyson
  1 sibling, 0 replies; 5+ messages in thread
From: Hugo Tyson @ 2001-09-05  0:10 UTC (permalink / raw)
  To: ecos-discuss


"Sorin Babeanu" <sorin@netappi.com> writes:
> The attached patch contains a few modifications I have made in order to make
> the loopback interface work on eCos without a real network device.
> It also contains tests for ping, udp and tcp.

Just to keep folks up to date: Sorin, thanks for that.  I'm in the process
of adopting it into the trunk - actually a variation on your patch which
sets up the loopback dev in init_all_network_interfaces(), and is more
configurable for 0,1,N loopback devs.

The tests are great, thanks, we can start to run meaningful network tests
on all platforms with those in place, I'll just be adding PASS/FAIL
messages so we can automate those in our test farm.

It'll all show up in anoncvs by the end of this week.

Is there any call for me to supply an alternative patch on this forum?
I won't do so unless people ask.  Any replies to the list please, not me.

	- Huge

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [ECOS] Loopback patch adopted OK
  2000-06-21 11:00   ` [ECOS] Loopback patch adopted OK Hugo Tyson
@ 2001-09-05  0:10     ` Hugo Tyson
  0 siblings, 0 replies; 5+ messages in thread
From: Hugo Tyson @ 2001-09-05  0:10 UTC (permalink / raw)
  To: ecos-discuss


Hugo Tyson <hmt@cygnus.co.uk> writes:
> "Sorin Babeanu" <sorin@netappi.com> writes:
> > The attached patch contains a few modifications I have made in order to make
> > the loopback interface work on eCos without a real network device.
> > It also contains tests for ping, udp and tcp.
> 
> Just to keep folks up to date: Sorin, thanks for that.  I'm in the process
> of adopting it into the trunk - actually a variation on your patch which
> sets up the loopback dev in init_all_network_interfaces(), and is more
> configurable for 0,1,N loopback devs.
> 
> The tests are great, thanks, we can start to run meaningful network tests
> on all platforms with those in place, I'll just be adding PASS/FAIL
> messages so we can automate those in our test farm.
> 
> It'll all show up in anoncvs by the end of this week.
> 
> Is there any call for me to supply an alternative patch on this forum?
> I won't do so unless people ask.  Any replies to the list please, not me.

Phew, done that... ;-)

Sorin, I didn't see what the change in if_loop.c (pasted below) achieved,
so I didn't adopt it.  Can you explain more, convince me?  (I have got the
location it patches right haven't I, ie. looutput()?)

It seems to just do a load of checking twice, in a different order; I mean
the original looutput() checks for RTF_REJECT|RTF_BLACKHOLE &c, and returns
EAFNOSUPPORT with a bad AF.  Was this just experimentation while you were
testing the startup code, that leaked out?

Anyway, thanks again for the contribution; keep up the good work!

Watch anoncvs for our updates to emerge... end of the week sometime.

	- Huge


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 int
 looutput(ifp, m, dst, rt)
        struct ifnet *ifp;
        register struct mbuf *m;
 	struct sockaddr *dst;
 	register struct rtentry *rt;
 {
+        if ((m->m_flags & M_PKTHDR) == 0)
+                panic("looutput no HDR");
+
+        if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
+                m_freem(m);
+                return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
+                        rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
+        }
+        ifp->if_opackets++;
+        ifp->if_obytes += m->m_pkthdr.len;
+#if 1   /* XXX */
+        switch (dst->sa_family) {
+        case AF_INET:
+        case AF_IPX:
+        case AF_NS:
+        case AF_ISO:
+        case AF_APPLETALK:
+                break;
+        default:
+                printf("looutput: af=%d unexpected", dst->sa_family);
+                m_freem(m);
+                return (EAFNOSUPPORT);
+        }
+#endif
+        return(if_simloop(ifp, m, dst, 0));
+}
+
+
+int
+if_simloop(ifp, m, dst, rt)
+	struct ifnet *ifp;
+	register struct mbuf *m;
+	struct sockaddr *dst;
+	register struct rtentry *rt;
+{
 	int s, isr;
 	register struct ifqueue *ifq = 0;
 
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2001-09-05  0:10 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2000-06-16  4:37 [ECOS] Loopback patch Sorin Babeanu
2000-06-21  4:15 ` Hugo Tyson
2000-06-21 11:00   ` [ECOS] Loopback patch adopted OK Hugo Tyson
2001-09-05  0:10     ` Hugo Tyson
2001-09-05  0:10   ` [ECOS] Loopback patch Hugo Tyson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).