]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/net/common/v2_0/tests/tcp_source.c
unified MX27, MX25, MX37 trees
[karo-tx-redboot.git] / packages / net / common / v2_0 / tests / tcp_source.c
1 //==========================================================================
2 //
3 //      tests/tcp_source.c
4 //
5 //      Simple TCP throughput test - source component
6 //      * CAUTION: host, i.e. non eCos, only *
7 //
8 //==========================================================================
9 //####BSDCOPYRIGHTBEGIN####
10 //
11 // -------------------------------------------
12 //
13 // Portions of this software may have been derived from OpenBSD or other sources,
14 // and are covered by the appropriate copyright disclaimers included herein.
15 //
16 // -------------------------------------------
17 //
18 //####BSDCOPYRIGHTEND####
19 //==========================================================================
20 //#####DESCRIPTIONBEGIN####
21 //
22 // Author(s):    gthomas
23 // Contributors: gthomas
24 // Date:         2000-01-10
25 // Purpose:      
26 // Description:  This is the middle part of a three part test.  The idea is
27 //   to test the throughput of box in a configuration like this:
28 //
29 //      +------+   port   +----+     port    +----+
30 //      |SOURCE|=========>|ECHO|============>|SINK|
31 //      +------+   9990   +----+     9991    +----+
32 // 
33 //
34 //####DESCRIPTIONEND####
35 //
36 //==========================================================================
37
38 // Network throughput test code
39
40 #undef _KERNEL
41 #include <stdlib.h>
42 #include <unistd.h>
43 #include <stdio.h>
44
45 #include <sys/param.h>
46 #include <sys/socket.h>
47 #include <sys/ioctl.h>
48 #include <sys/errno.h>
49 #include <sys/time.h>
50
51 #include <net/if.h>
52 #include <netinet/in_systm.h>
53 #include <netinet/in.h>
54 #include <netinet/ip.h>
55 #include <netinet/ip_icmp.h>
56
57 #include <netdb.h>
58
59 #define SOURCE_PORT 9990
60 #define SINK_PORT   9991
61
62 struct test_params {
63     long nbufs;
64     long bufsize;
65     long load;
66 };
67
68 struct test_status {
69     long ok;
70 };
71
72 #define NUM_BUF 1024
73 #define MAX_BUF 8192
74 static unsigned char data_buf[MAX_BUF];
75
76 void
77 pexit(char *s)
78 {
79     perror(s);
80     exit(1);
81 }
82
83 void
84 show_results(struct timeval *start, struct timeval *end, 
85              int nbufs, int buflen)
86 {
87     struct timeval tot_time;
88     long tot_bytes = nbufs * buflen;
89     double real_time, thru;
90     timersub(end, start, &tot_time);
91     printf("SOURCE complete - %d bufs of %d bytes in %ld.%02ld seconds",
92            nbufs, buflen, 
93            tot_time.tv_sec, tot_time.tv_usec / 10000);
94     real_time = tot_time.tv_sec + ((tot_time.tv_usec / 10000) * .01);
95     // Compute bytes / second (rounded up)
96     thru = tot_bytes / real_time;
97     // Convert to Mb / second
98     printf(" - %.2f KB/S", thru / 1024.0);
99     printf(" - %.4f Mbit/S (M = 10^6)", thru * 8.0 / 1000000.0);
100     printf("\n");
101 }
102
103 int
104 do_read(int s, unsigned char *buf, int len)
105 {
106     int total, slen, rlen;
107     total = 0;
108     rlen = len;
109     while (total < len) {
110         slen = read(s, buf, rlen);
111         if (slen != rlen) {
112             if (slen < 0) {
113                 printf("Error after reading %d bytes\n", total);
114                 return -1;
115             }
116             rlen -= slen;
117             buf += slen;
118         }
119         total += slen;
120     }
121     return total;
122 }
123
124 int
125 do_write(int s, unsigned char *buf, int len)
126 {
127     int total, slen, rlen;
128     total = 0;
129     rlen = len;
130     while (total < len) {
131         slen = write(s, buf, rlen);
132         if (slen != rlen) {
133             if (slen < 0) {
134                 printf("Error after writing %d bytes\n", total);
135                 return -1;
136             }
137             rlen -= slen;
138             buf += slen;
139         }
140         total += slen;
141     }
142     return total;
143 }
144
145 static void
146 source_test(char *echo_node, int load)
147 {
148     int s_source;
149     struct sockaddr_in slave, local;
150     int one = 1;
151     int len;
152     struct hostent *host;
153     struct test_params params;
154     struct test_params nparams;
155     struct test_status status;
156     struct test_status nstatus;
157     struct timeval start_time, end_time;
158     int i;
159
160     printf("Start TCP test - SOURCE mode to %s\n", echo_node);
161
162     host = gethostbyname(echo_node);
163     if (host == (struct hostent *)NULL) {
164         pexit("gethostbyname");
165     }
166
167     memset(&slave, 0, sizeof(slave));
168     slave.sin_family = AF_INET;
169 #ifdef __ECOS
170     slave.sin_len = sizeof(slave);
171 #endif
172     slave.sin_port = htons(SOURCE_PORT);
173     memcpy(&slave.sin_addr.s_addr, host->h_addr, host->h_length);
174
175     s_source = socket(AF_INET, SOCK_STREAM, 0);
176     if (s_source < 0) {
177         pexit("stream socket");
178     }
179     if (setsockopt(s_source, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one))) {
180         pexit("setsockopt /source/ SO_REUSEADDR");
181     }
182     memset(&local, 0, sizeof(local));
183     local.sin_family = AF_INET;
184 #ifdef __ECOS
185     local.sin_len = sizeof(local);
186 #endif
187     local.sin_port = INADDR_ANY;
188     local.sin_addr.s_addr = INADDR_ANY;
189     if(bind(s_source, (struct sockaddr *) &local, sizeof(local)) < 0) {
190         pexit("bind /source/ error");
191     }
192
193     if (connect(s_source, (struct sockaddr *)&slave, sizeof(slave)) < 0) { 
194         pexit("Can't connect to target");
195     }
196
197     params.nbufs = NUM_BUF;
198     params.bufsize = MAX_BUF;
199     params.load = load;
200    
201     nparams.nbufs = htonl(params.nbufs);
202     nparams.bufsize = htonl(params.bufsize);
203     nparams.load = htonl(params.load);
204    
205     if ( do_write(s_source, (unsigned char *)&nparams, sizeof(nparams))
206                   != sizeof(params)) {
207         pexit("Can't send initialization parameters");
208     }
209     if (do_read(s_source, (unsigned char *)&nstatus, sizeof(nstatus))
210                   != sizeof(status)) {
211         pexit("Can't get status from 'echo' client");
212     }
213
214     status.ok = ntohl(nstatus.ok);
215    
216     // Actual test
217     gettimeofday(&start_time, 0);
218     for (i = 0;  i < params.nbufs;  i++) {
219         if ((len = do_write(s_source, data_buf, params.bufsize)) != params.bufsize) {
220             printf("Error writing buffer #%d:", i+1);
221             if (len < 0) {
222                 perror("can't write data");
223             } else {
224                 printf(" short data, only wrote %d bytes\n", len);
225             }
226         }
227     }
228     gettimeofday(&end_time, 0);
229     show_results(&start_time, &end_time, params.nbufs, params.bufsize);
230 }
231
232 int
233 main(int argc, char *argv[])
234 {
235     int load = 0;
236     if (argc > 2) {
237         load = atoi(argv[2]);
238     }
239     source_test(argv[1], load);
240    return 0;
241 }
242