OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [common/] [current/] [tests/] [flood.c] - Blame information for rev 856

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      tests/flood.c
4
//
5
//      Flood PING test
6
//
7
//==========================================================================
8
// ####BSDALTCOPYRIGHTBEGIN####                                             
9
// -------------------------------------------                              
10
// Portions of this software may have been derived from FreeBSD, OpenBSD,   
11
// or other sources, and if so are covered by the appropriate copyright     
12
// and license included herein.                                             
13
// -------------------------------------------                              
14
// ####BSDALTCOPYRIGHTEND####                                               
15
//==========================================================================
16
//#####DESCRIPTIONBEGIN####
17
//
18
// Author(s):    gthomas, hmt
19
// Contributors: gthomas
20
// Date:         2000-05-03
21
// Purpose:      
22
// Description:  
23
//              
24
//
25
//####DESCRIPTIONEND####
26
//
27
//==========================================================================
28
 
29
#include <pkgconf/system.h>
30
#include <pkgconf/net.h>
31
 
32
#ifdef CYGBLD_DEVS_ETH_DEVICE_H    // Get the device config if it exists
33
#include CYGBLD_DEVS_ETH_DEVICE_H  // May provide CYGTST_DEVS_ETH_TEST_NET_REALTIME
34
#endif
35
 
36
#ifdef CYGPKG_NET_TESTS_USE_RT_TEST_HARNESS // do we use the rt test?
37
# ifdef CYGTST_DEVS_ETH_TEST_NET_REALTIME // Get the test ancilla if it exists
38
#  include CYGTST_DEVS_ETH_TEST_NET_REALTIME
39
# endif
40
#endif
41
 
42
 
43
// Fill in the blanks if necessary
44
#ifndef TNR_OFF
45
# define TNR_OFF()
46
#endif
47
#ifndef TNR_ON
48
# define TNR_ON()
49
#endif
50
#ifndef TNR_INIT
51
# define TNR_INIT()
52
#endif
53
#ifndef TNR_PRINT_ACTIVITY
54
# define TNR_PRINT_ACTIVITY()
55
#endif
56
 
57
 
58
// FLOOD PING test code
59
 
60
#include <network.h>
61
 
62
#define MAX_PACKET 4096
63
 
64
#define NUMTHREADS 3
65
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + MAX_PACKET + MAX_PACKET + 0x1000)
66
static char thread_stack[NUMTHREADS][STACK_SIZE];
67
static cyg_thread thread_data[NUMTHREADS];
68
static cyg_handle_t thread_handle[NUMTHREADS];
69
 
70
#define DO_DUMPSTATS( seq ) (0 == (0xffff & seq))
71
 
72
#ifdef CYGHWR_NET_DRIVER_ETH0
73
struct sockaddr_in host0;
74
#endif
75
#ifdef CYGHWR_NET_DRIVER_ETH1
76
struct sockaddr_in host1;
77
#endif
78
static int sock;
79
 
80
static int uniqueid[3] = { 0x1234, 0x4321, 0xdead };
81
 
82
static int ok_recv[3] = { 0,0,0 };
83
static int bogus_recv[3] = { 0,0,0 };
84
static int pings_sent[3] = { 0,0,0 };
85
 
86
extern void cyg_kmem_print_stats( void );
87
 
88
extern void
89
cyg_test_exit(void);
90
 
91
void
92
pexit(char *s)
93
{
94
    perror(s);
95
    cyg_test_exit();
96
}
97
 
98
// ------------------------------------------------------------------------
99
static void dumpstats(void)
100
{
101
    TNR_OFF();
102
    diag_printf( "------------------------\n" );
103
#ifdef CYGHWR_NET_DRIVER_ETH0
104
    if (eth0_up) {
105
        diag_printf("%16s: Sent %d packets, received %d OK, %d bad\n",
106
                    inet_ntoa(host0.sin_addr), pings_sent[0],
107
                    ok_recv[0], bogus_recv[0]);
108
    }
109
#endif
110
#ifdef CYGHWR_NET_DRIVER_ETH1
111
    if (eth1_up) {
112
        diag_printf("%16s: Sent %d packets, received %d OK, %d bad\n",
113
                    inet_ntoa(host1.sin_addr), pings_sent[1],
114
                    ok_recv[1], bogus_recv[1]);
115
    }
116
#endif
117
    if ( pings_sent[2] )
118
        diag_printf("Wierd!  %d unknown sends!\n", pings_sent[2] );
119
    if ( ok_recv[2] )
120
        diag_printf("Wierd!  %d unknown good recvs!\n", ok_recv[2] );
121
    if ( bogus_recv[2] )
122
        diag_printf("Wierd!  %d unknown bogus recvs!\n", bogus_recv[2] );
123
    cyg_kmem_print_stats();
124
    diag_printf( "------------------------\n" );
125
    TNR_ON();
126
}
127
 
128
 
129
// ------------------------------------------------------------------------
130
// Compute INET checksum
131
int
132
inet_cksum(u_short *addr, int len)
133
{
134
    register int nleft = len;
135
    register u_short *w = addr;
136
    register u_short answer;
137
    register u_int sum = 0;
138
    u_short odd_byte = 0;
139
 
140
    /*
141
     *  Our algorithm is simple, using a 32 bit accumulator (sum),
142
     *  we add sequential 16 bit words to it, and at the end, fold
143
     *  back all the carry bits from the top 16 bits into the lower
144
     *  16 bits.
145
     */
146
    while( nleft > 1 )  {
147
        sum += *w++;
148
        nleft -= 2;
149
    }
150
 
151
    /* mop up an odd byte, if necessary */
152
    if( nleft == 1 ) {
153
        *(u_char *)(&odd_byte) = *(u_char *)w;
154
        sum += odd_byte;
155
    }
156
 
157
    /*
158
     * add back carry outs from top 16 bits to low 16 bits
159
     */
160
    sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */
161
    sum += (sum >> 16);                     /* add carry */
162
    answer = ~sum;                          /* truncate to 16 bits */
163
    return (answer);
164
}
165
 
166
// ------------------------------------------------------------------------
167
static void
168
show_icmp(unsigned char *pkt, int len, struct sockaddr_in *from)
169
{
170
    cyg_tick_count_t *tp, tv;
171
    struct ip *ip;
172
    struct icmp *icmp;
173
    int which = 2;
174
    tv = cyg_current_time();
175
#ifdef CYGHWR_NET_DRIVER_ETH0
176
    if (eth0_up && (from->sin_addr.s_addr == host0.sin_addr.s_addr) )
177
        which = 0;
178
#endif
179
#ifdef CYGHWR_NET_DRIVER_ETH1
180
    if (eth1_up && (from->sin_addr.s_addr == host1.sin_addr.s_addr) )
181
        which = 1;
182
#endif
183
 
184
    ip = (struct ip *)pkt;
185
    if ((len < sizeof(*ip)) || ip->ip_v != IPVERSION) {
186
        diag_printf("%s: Short packet or not IP! - Len: %d, Version: %d\n",
187
                    inet_ntoa(from->sin_addr), len, ip->ip_v);
188
        bogus_recv[which]++;
189
        return;
190
    }
191
    icmp = (struct icmp *)(pkt + sizeof(*ip));
192
    len -= (sizeof(*ip) + 8);
193
    tp = (cyg_tick_count_t *)&icmp->icmp_data;
194
    if (icmp->icmp_type != ICMP_ECHOREPLY) {
195
        diag_printf("%s: Invalid ICMP - type: %d\n",
196
                    inet_ntoa(from->sin_addr), icmp->icmp_type);
197
        bogus_recv[which]++;
198
        return;
199
    }
200
    ok_recv[which]++;
201
    if (icmp->icmp_id != uniqueid[which]) {
202
        diag_printf("%s: ICMP received for wrong id - sent: %x, recvd: %x\n",
203
                    inet_ntoa(from->sin_addr), uniqueid[which], icmp->icmp_id);
204
    }
205
//    diag_printf("%d bytes from %s: ", len, inet_ntoa(from->sin_addr));
206
//    diag_printf("icmp_seq=%d", icmp->icmp_seq);
207
//    diag_printf(", time=%dms\n", (int)(tv - *tp)*10);
208
}
209
 
210
// ------------------------------------------------------------------------
211
static void
212
floodrecv(cyg_addrword_t p)
213
{
214
    unsigned char pkt[MAX_PACKET];
215
    struct sockaddr_in from;
216
    int len;
217
    socklen_t fromlen;
218
 
219
    diag_printf("PING listener...\n" );
220
    for (;;) {
221
        // Wait for a response
222
        fromlen = sizeof(from);
223
        len = recvfrom(sock, pkt, sizeof(pkt), 0,
224
                       (struct sockaddr *)&from, &fromlen);
225
        if (len < 0)
226
            perror("recvfrom");
227
        else
228
            show_icmp(pkt, len, &from);
229
    }
230
}
231
 
232
// ------------------------------------------------------------------------
233
static void
234
pingsend( int seq, struct sockaddr_in *host,
235
          struct icmp *icmp, int icmp_len, int which )
236
{
237
    cyg_tick_count_t *tp;
238
    long *dp;
239
    int i;
240
    // Build ICMP packet for interface
241
    icmp->icmp_type = ICMP_ECHO;
242
    icmp->icmp_code = 0;
243
    icmp->icmp_cksum = 0;
244
    icmp->icmp_seq = seq;
245
    icmp->icmp_id = uniqueid[which];
246
    // Set up ping data
247
    tp = (cyg_tick_count_t *)&icmp->icmp_data;
248
    *tp++ = cyg_current_time();
249
    dp = (long *)tp;
250
    for (i = sizeof(*tp);  i < icmp_len;  i += sizeof(*dp))
251
        *dp++ = i;
252
 
253
    // Add checksum
254
    icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8);
255
    // Send it off
256
    if (sendto(sock, icmp, icmp_len+8, MSG_DONTWAIT,
257
              (struct sockaddr *)host, sizeof(*host)) < 0) {
258
        perror("sendto");
259
    }
260
    pings_sent[which]++;
261
}
262
 
263
// ------------------------------------------------------------------------
264
static void
265
floodsend(cyg_addrword_t param)
266
{
267
#ifdef CYGHWR_NET_DRIVER_ETH0
268
    unsigned char pkt0[MAX_PACKET];
269
    struct icmp *icmp0 = (struct icmp *)pkt0;
270
#endif
271
#ifdef CYGHWR_NET_DRIVER_ETH1
272
    unsigned char pkt1[MAX_PACKET];
273
    struct icmp *icmp1 = (struct icmp *)pkt1;
274
#endif
275
 
276
    int icmp_len = 64;
277
    int seq;
278
 
279
    for (seq = 0; 1 ; seq++) {
280
        if ( DO_DUMPSTATS( seq ) )
281
            dumpstats();
282
 
283
#ifdef CYGHWR_NET_DRIVER_ETH0
284
        if (eth0_up)
285
            pingsend( seq, &host0, icmp0, icmp_len, 0 );
286
#endif
287
#ifdef CYGHWR_NET_DRIVER_ETH1
288
        if (eth1_up)
289
            pingsend( seq, &host1, icmp1, icmp_len, 1 );
290
#endif
291
    }
292
}
293
 
294
 
295
// ------------------------------------------------------------------------
296
void
297
net_test(cyg_addrword_t param)
298
{
299
    struct protoent *p;
300
 
301
    diag_printf("Start Flood PING test\n");
302
    init_all_network_interfaces();
303
    diag_printf("Interfaces up:\n");
304
    cyg_kmem_print_stats();
305
 
306
    TNR_INIT();
307
 
308
    if ((p = getprotobyname("icmp")) == (struct protoent *)0) {
309
        perror("getprotobyname");
310
        return;
311
    }
312
    sock = socket(AF_INET, SOCK_RAW, p->p_proto);
313
    if (sock < 0) {
314
        perror("tx socket");
315
        return;
316
    }
317
 
318
#ifdef CYGHWR_NET_DRIVER_ETH0
319
    if (eth0_up) {
320
        host0.sin_family = AF_INET;
321
        host0.sin_len = sizeof(host0);
322
        host0.sin_addr = eth0_bootp_data.bp_siaddr;
323
        host0.sin_port = 0;
324
        diag_printf("PING server %16s\n", inet_ntoa(host0.sin_addr));
325
    }
326
#endif
327
#ifdef CYGHWR_NET_DRIVER_ETH1
328
    if (eth1_up) {
329
        host1.sin_family = AF_INET;
330
        host1.sin_len = sizeof(host1);
331
        host1.sin_addr = eth1_bootp_data.bp_siaddr;
332
        host1.sin_port = 0;
333
        diag_printf("PING server %16s\n", inet_ntoa(host1.sin_addr));
334
    }
335
#endif
336
 
337
    cyg_thread_resume(thread_handle[1]);
338
    cyg_thread_resume(thread_handle[2]);
339
 
340
    cyg_thread_delay( 100 ); // let the other threads start and print
341
 
342
    TNR_ON();                // then enable the test
343
 
344
    cyg_thread_delay( 12000 ); // run for a couple of minutes
345
 
346
    TNR_OFF();
347
 
348
    diag_printf("After running:\n");
349
    dumpstats();
350
    TNR_PRINT_ACTIVITY();
351
    cyg_test_exit();
352
}
353
 
354
// ------------------------------------------------------------------------
355
void
356
cyg_start(void)
357
{
358
    // Create a main thread, so we can run the scheduler and have time 'pass'
359
    cyg_thread_create(10,                // Priority - just a number
360
                      net_test,          // entry
361
                      0,                 // entry parameter
362
                      "Network test",    // Name
363
                     &thread_stack[0][0], // Stack
364
                      STACK_SIZE,        // Size
365
                      &thread_handle[0], // Handle
366
                      &thread_data[0]    // Thread data structure
367
            );
368
    cyg_thread_resume(thread_handle[0]);  // Start it
369
 
370
    // Create the secondary threads
371
    cyg_thread_create(11,                // Priority - just a number
372
                      floodrecv,         // entry
373
                      0,                 // entry parameter
374
                      "Flood Ping Recv", // Name
375
                     &thread_stack[1][0], // Stack
376
                      STACK_SIZE,        // Size
377
                      &thread_handle[1], // Handle
378
                      &thread_data[1]    // Thread data structure
379
            );
380
    cyg_thread_create(12,                // Priority - just a number
381
                      floodsend,         // entry
382
                      0,                 // entry parameter
383
                      "Flood Ping Send", // Name
384
                     &thread_stack[2][0], // Stack
385
                      STACK_SIZE,        // Size
386
                      &thread_handle[2], // Handle
387
                      &thread_data[2]    // Thread data structure
388
            );
389
 
390
 
391
    cyg_scheduler_start();
392
}
393
 
394
// EOF flood.c
395
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.