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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [net/] [ppp/] [current/] [tests/] [ppp_updown.c] - Blame information for rev 786

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 786 skrzyp
//==========================================================================
2
//
3
//      tests/ppp_updown.c
4
//
5
//      Simple test of PPP and networking support
6
//
7
//==========================================================================
8
// ####ECOSGPLCOPYRIGHTBEGIN####                                            
9
// -------------------------------------------                              
10
// This file is part of eCos, the Embedded Configurable Operating System.   
11
// Copyright (C) 2003 Free Software Foundation, Inc.                        
12
//
13
// eCos is free software; you can redistribute it and/or modify it under    
14
// the terms of the GNU General Public License as published by the Free     
15
// Software Foundation; either version 2 or (at your option) any later      
16
// version.                                                                 
17
//
18
// eCos is distributed in the hope that it will be useful, but WITHOUT      
19
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or    
20
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License    
21
// for more details.                                                        
22
//
23
// You should have received a copy of the GNU General Public License        
24
// along with eCos; if not, write to the Free Software Foundation, Inc.,    
25
// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            
26
//
27
// As a special exception, if other files instantiate templates or use      
28
// macros or inline functions from this file, or you compile this file      
29
// and link it with other works to produce a work based on this file,       
30
// this file does not by itself cause the resulting work to be covered by   
31
// the GNU General Public License. However the source code for this file    
32
// must still be made available in accordance with section (3) of the GNU   
33
// General Public License v2.                                               
34
//
35
// This exception does not invalidate any other reasons why a work based    
36
// on this file might be covered by the GNU General Public License.         
37
// -------------------------------------------                              
38
// ####ECOSGPLCOPYRIGHTEND####                                              
39
// ####BSDALTCOPYRIGHTBEGIN####                                             
40
// -------------------------------------------                              
41
// Portions of this software may have been derived from FreeBSD, OpenBSD,   
42
// or other sources, and if so are covered by the appropriate copyright     
43
// and license included herein.                                             
44
// -------------------------------------------                              
45
// ####BSDALTCOPYRIGHTEND####                                               
46
//==========================================================================
47
//#####DESCRIPTIONBEGIN####
48
//
49
// Author(s):    nickg
50
// Contributors: gthomas (ping code), nickg
51
// Date:         2003-06-01
52
// Purpose:      
53
// Description:  
54
//              
55
//
56
//####DESCRIPTIONEND####
57
//
58
//==========================================================================
59
 
60
// PPP test code
61
 
62
#include <network.h>
63
 
64
#include <pkgconf/system.h>
65
#include <pkgconf/net.h>
66
 
67
#include "ppp_test_support.inl"
68
 
69
//==========================================================================
70
 
71
typedef void pr_fun(char *fmt, ...);
72
 
73
externC void show_network_tables(pr_fun *pr);
74
 
75
//==========================================================================
76
 
77
#include <arpa/inet.h>
78
 
79
// Fill in the blanks if necessary
80
#ifndef TNR_OFF
81
# define TNR_OFF()
82
#endif
83
#ifndef TNR_ON
84
# define TNR_ON()
85
#endif
86
#ifndef TNR_INIT
87
# define TNR_INIT()
88
#endif
89
#ifndef TNR_PRINT_ACTIVITY
90
# define TNR_PRINT_ACTIVITY()
91
#endif
92
 
93
#define NUM_PINGS 16
94
#define MAX_PACKET 4096
95
#define MIN_PACKET   64
96
#define MAX_SEND   4000
97
 
98
#define PACKET_ADD  ((MAX_SEND - MIN_PACKET)/NUM_PINGS)
99
#define nPACKET_ADD  1 
100
 
101
static unsigned char pkt1[MAX_PACKET], pkt2[MAX_PACKET];
102
 
103
#define UNIQUEID 0x1234
104
 
105
void
106
pexit(char *s)
107
{
108
    CYG_TEST_FAIL_FINISH(s);
109
}
110
 
111
// Compute INET checksum
112
int
113
inet_cksum(u_short *addr, int len)
114
{
115
    register int nleft = len;
116
    register u_short *w = addr;
117
    register u_short answer;
118
    register u_int sum = 0;
119
    u_short odd_byte = 0;
120
 
121
    /*
122
     *  Our algorithm is simple, using a 32 bit accumulator (sum),
123
     *  we add sequential 16 bit words to it, and at the end, fold
124
     *  back all the carry bits from the top 16 bits into the lower
125
     *  16 bits.
126
     */
127
    while( nleft > 1 )  {
128
        sum += *w++;
129
        nleft -= 2;
130
    }
131
 
132
    /* mop up an odd byte, if necessary */
133
    if( nleft == 1 ) {
134
        *(u_char *)(&odd_byte) = *(u_char *)w;
135
        sum += odd_byte;
136
    }
137
 
138
    /*
139
     * add back carry outs from top 16 bits to low 16 bits
140
     */
141
    sum = (sum >> 16) + (sum & 0x0000ffff); /* add hi 16 to low 16 */
142
    sum += (sum >> 16);                     /* add carry */
143
    answer = ~sum;                          /* truncate to 16 bits */
144
    return (answer);
145
}
146
 
147
static int
148
show_icmp(unsigned char *pkt, int len,
149
          struct sockaddr_in *from, struct sockaddr_in *to)
150
{
151
#if 1
152
    cyg_tick_count_t *tp, tv;
153
    struct ip *ip;
154
    struct icmp *icmp;
155
    tv = cyg_current_time();
156
    ip = (struct ip *)pkt;
157
    if ((len < sizeof(*ip)) || ip->ip_v != IPVERSION) {
158
        diag_printf("%s: Short packet or not IP! - Len: %d, Version: %d\n",
159
                    inet_ntoa(from->sin_addr), len, ip->ip_v);
160
        return 0;
161
    }
162
    icmp = (struct icmp *)(pkt + sizeof(*ip));
163
    len -= (sizeof(*ip) + 8);
164
    tp = (cyg_tick_count_t *)&icmp->icmp_data;
165
    if (icmp->icmp_type != ICMP_ECHOREPLY) {
166
        diag_printf("%s: Invalid ICMP - type: %d\n",
167
                    inet_ntoa(from->sin_addr), icmp->icmp_type);
168
        return 0;
169
    }
170
    if (icmp->icmp_id != UNIQUEID) {
171
        diag_printf("%s: ICMP received for wrong id - sent: %x, recvd: %x\n",
172
                    inet_ntoa(from->sin_addr), UNIQUEID, icmp->icmp_id);
173
    }
174
    diag_printf("%d bytes from %s: ", len, inet_ntoa(from->sin_addr));
175
    diag_printf("icmp_seq=%d", icmp->icmp_seq);
176
    diag_printf(", time=%dms\n", (int)(tv - *tp)*10);
177
    return (from->sin_addr.s_addr == to->sin_addr.s_addr);
178
#else
179
    return 1;
180
#endif
181
}
182
 
183
static void
184
ping_host(int s, struct sockaddr_in *host)
185
{
186
    struct icmp *icmp = (struct icmp *)pkt1;
187
    int icmp_len = MIN_PACKET;
188
    int seq, ok_recv, bogus_recv;
189
    cyg_tick_count_t *tp;
190
    long *dp;
191
    struct sockaddr_in from;
192
    int i, len, fromlen;
193
 
194
    ok_recv = 0;
195
    bogus_recv = 0;
196
    diag_printf("PING server %s\n", inet_ntoa(host->sin_addr));
197
    for (seq = 0;  seq < NUM_PINGS;  seq++, icmp_len += PACKET_ADD ) {
198
        TNR_ON();
199
        // Build ICMP packet
200
        icmp->icmp_type = ICMP_ECHO;
201
        icmp->icmp_code = 0;
202
        icmp->icmp_cksum = 0;
203
        icmp->icmp_seq = seq;
204
        icmp->icmp_id = 0x1234;
205
        // Set up ping data
206
        tp = (cyg_tick_count_t *)&icmp->icmp_data;
207
        *tp++ = cyg_current_time();
208
        dp = (long *)tp;
209
        for (i = sizeof(*tp);  i < icmp_len;  i += sizeof(*dp)) {
210
            *dp++ = i;
211
        }
212
        // Add checksum
213
        icmp->icmp_cksum = inet_cksum( (u_short *)icmp, icmp_len+8);
214
        // Send it off
215
        if (sendto(s, icmp, icmp_len+8, 0, (struct sockaddr *)host, sizeof(*host)) < 0) {
216
            TNR_OFF();
217
            perror("sendto");
218
            continue;
219
        }
220
        // Wait for a response
221
        fromlen = sizeof(from);
222
        len = recvfrom(s, pkt2, sizeof(pkt2), 0, (struct sockaddr *)&from, &fromlen);
223
        TNR_OFF();
224
        if (len < 0) {
225
            perror("recvfrom");
226
            icmp_len = MIN_PACKET - PACKET_ADD; // just in case - long routes
227
        } else {
228
            if (show_icmp(pkt2, len, &from, host)) {
229
                ok_recv++;
230
            } else {
231
                bogus_recv++;
232
            }
233
        }
234
    }
235
    TNR_OFF();
236
    diag_printf("Sent %d packets, received %d OK, %d bad\n", NUM_PINGS, ok_recv, bogus_recv);
237
}
238
 
239
static void do_ping(void)
240
{
241
    struct protoent *p;
242
    struct timeval tv;
243
    struct sockaddr_in host;
244
    int s;
245
 
246
    if ((p = getprotobyname("icmp")) == (struct protoent *)0) {
247
        pexit("getprotobyname");
248
        return;
249
    }
250
    s = socket(AF_INET, SOCK_RAW, p->p_proto);
251
    if (s < 0) {
252
        pexit("socket");
253
        return;
254
    }
255
    tv.tv_sec = 7;
256
    tv.tv_usec = 0;
257
    setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
258
    // Set up host address
259
    host.sin_family = AF_INET;
260
    host.sin_len = sizeof(host);
261
    host.sin_port = 0;
262
 
263
    // Set a default remote end address
264
    inet_aton("10.0.0.100", &host.sin_addr);
265
 
266
    // Now quiz the ppp0 interface for its destination address and use
267
    // that as our ping-buddy.
268
    {
269
        struct ifreq ifr;
270
        int sock = socket(AF_INET, SOCK_DGRAM, 0);
271
 
272
        if( sock != -1 )
273
        {
274
            strncpy( ifr.ifr_name, "ppp0", sizeof(ifr.ifr_name));
275
            if( ioctl( sock, SIOCGIFDSTADDR, &ifr ) == 0 )
276
                host.sin_addr = ((struct sockaddr_in *)&ifr.ifr_dstaddr)->sin_addr;
277
 
278
            close(sock);
279
        }
280
    }
281
 
282
    ping_host(s, &host);
283
 
284
}
285
 
286
//==========================================================================
287
 
288
#define STACK_SIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 0x1000)
289
static char stack[STACK_SIZE];
290
static cyg_thread thread_data;
291
static cyg_handle_t thread_handle;
292
 
293
 
294
//==========================================================================
295
 
296
static void do_test( cyg_serial_baud_rate_t baud )
297
{
298
    cyg_ppp_options_t options;
299
    cyg_ppp_handle_t ppp_handle;
300
 
301
    ppp_test_announce( "PPP_UPDOWN" );
302
 
303
    cyg_ppp_options_init( &options );
304
 
305
//    options.debug = 1;
306
//    options.kdebugflag = 1;
307
 
308
    options.baud = baud;
309
 
310
    ppp_handle = cyg_ppp_up( CYGPKG_PPP_TEST_DEVICE, &options );
311
 
312
    CYG_TEST_INFO( "Waiting for PPP to come up");
313
 
314
    cyg_ppp_wait_up( ppp_handle );
315
 
316
//    show_network_tables( diag_printf );
317
 
318
    CYG_TEST_INFO( "Delaying...");
319
 
320
    cyg_thread_delay(10*100);
321
 
322
    CYG_TEST_INFO( "Pinging remote");
323
 
324
    do_ping();
325
 
326
//    show_network_tables( diag_printf );
327
 
328
    CYG_TEST_INFO( "Bringing PPP down");
329
 
330
    cyg_ppp_down( ppp_handle );
331
 
332
    CYG_TEST_INFO( "Waiting for PPP to go down");
333
 
334
    cyg_ppp_wait_down( ppp_handle );
335
}
336
 
337
//==========================================================================
338
 
339
void
340
ppp_test(cyg_addrword_t p)
341
{
342
    cyg_serial_baud_rate_t old;
343
 
344
    CYG_TEST_INIT();
345
    diag_printf("Start PPP test\n");
346
 
347
    init_all_network_interfaces();
348
 
349
    old = ppp_test_set_baud( CYGNUM_SERIAL_BAUD_115200 );
350
    do_test( CYGNUM_SERIAL_BAUD_115200 );
351
 
352
#ifdef CYGPKG_PPP_TESTS_AUTOMATE
353
 
354
    CYG_TEST_INFO( "Delaying...");
355
    cyg_thread_delay(10*100);
356
 
357
    {
358
        static cyg_serial_baud_rate_t test_rates[] =
359
            { CYGDAT_PPP_TEST_BAUD_RATES, 0 };
360
 
361
        int i;
362
 
363
        for( i = 0; test_rates[i] != 0; i++ )
364
        {
365
            ppp_test_set_baud( test_rates[i] );
366
            do_test( test_rates[i] );
367
 
368
            CYG_TEST_INFO( "Delaying...");
369
            cyg_thread_delay(10*100);
370
 
371
        }
372
 
373
        ppp_test_set_baud( old );
374
 
375
        ppp_test_finish();
376
 
377
    }
378
 
379
#endif
380
 
381
    CYG_TEST_PASS_FINISH("PPP test OK");
382
}
383
 
384
//==========================================================================
385
 
386
void
387
cyg_start(void)
388
{
389
    // Create a main thread, so we can run the scheduler and have time 'pass'
390
    cyg_thread_create(10,                // Priority - just a number
391
                      ppp_test,          // entry
392
                      0,                 // entry parameter
393
                      "PPP test",        // Name
394
                      &stack[0],         // Stack
395
                      STACK_SIZE,        // Size
396
                      &thread_handle,    // Handle
397
                      &thread_data       // Thread data structure
398
            );
399
    cyg_thread_resume(thread_handle);  // Start it
400
    cyg_scheduler_start();
401
}
402
 
403
//==========================================================================

powered by: WebSVN 2.1.0

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