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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [ecos-2.0/] [packages/] [net/] [common/] [v2_0/] [tests/] [flood.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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